停止异步功能而不等待它完成

时间:2018-03-08 21:17:57

标签: node.js

在我的系统中,每隔几秒运行一次更新程序功能,此功能如下所示:

{{1}}

我调用updater函数一次,它应该在上次更新后5秒再次更新并运行。

由于updatesFromInternet函数是一个异步函数,我只能等待它完成,然后决定是否继续更新,而不是在它当前正在等待的位置停止它(获取互联网数据)。

是否有一种简单的方法可以立即停止更新而无需等待异步函数返回?

2 个答案:

答案 0 :(得分:0)

是的,只要您有对计时器句柄的引用:

clearTimeout(this.updater)

答案 1 :(得分:0)

而不是updater是一个函数,我会把它作为一个对象。即使有取消功能,如果您在前一个功能被取消之前调用updater功能,this.updater将被覆盖,您无法取消该计时器,它将永远持续。

以下示例使用IIFE封装其变量,并使用startstop方法返回对象。



const elOutput = document.getElementById('output'),
  elStatus = document.getElementById('status');
const url = '';

// IIFE that returns the updater object
const updater = (function () {
  let timer = null;
  let update = function () {
    timer = setTimeout(async () => {
      elStatus.textContent = 'Waiting for data...';
      let data = await updatingFromInternet(url);

      // if timer has been set to null, updates have been
      // cancelled
      if (timer !== null) {

        // do something with data here
        elOutput.textContent = data;
        elStatus.textContent = 'Updating...';
        update();
      }
    }, 5000);
  };

  let start = () => {
    // if the timer is not already running...
    if (timer === null) {
      elStatus.textContent = 'Starting update timer...';
      update();
    }
  };

  let stop = () => {
    clearTimeout(timer);
    timer = null;
    elStatus.textContent = 'Updates Canceled';
  };

  // return our updater object with its start and stop methods
  return {
    start,
    stop
  };
}());

document.getElementById('update').addEventListener('click', updater.start, false);
document.getElementById('cancel').addEventListener('click', updater.stop, false);

// mocking a networks response
const updatingFromInternet = (function () {
  let counter = 0;
  return function (url) {
    return new Promise((res, rej) => {
      setTimeout(res.bind(null, counter++), 1000);
    });
  };
}());

<button type="button" id="update">Update</button>
<button type="button" id="cancel">Cancel updates</button>
<div id="output"></div>
<div id="status"></div>
&#13;
&#13;
&#13;

更好的是,既然你正在使用Node,那么这就是放入module的理想选择。

// updater.js
let updatingFromInternet = require('./updatingFromInternet.js');
let timer = null;
let callback = null;

let update = function () {
  timer = setTimeout(async () => {
    let data = await updatingFromInternet(url);
    // if timer has been set to null, updates have been
    // cancelled
    if (timer !== null) {
      callback(data);
      update();
    }
  }, 5000);
};

let start = (userCallback) => {
  // if the timer is not already running
  // and we received a callback function
  if (timer === null && typeof userCallback === 'function') {
    callback = userCallback;
    update();
  }
};

let stop = () => {
  clearTimeout(timer);
  timer = null;
};

module.exports = {
  start,
  stop
};

然后,要使用它,require在主文件中:

let updater = require('./updater.js');
updater(function (data) {
  console.log(data);
}