取消javascript中的回调

Cancel a callback in javascript

本文关键字:回调 javascript 取消      更新时间:2023-09-26

我有类似的东西:

function MyObject() {
  var self = this;
  this.callback = function() {
    self.finishParams = Array.prototype.slice.call(arguments);
    self.parent.finish();
  }
  this.start = function() {
    this.currentCallback = this.callback
    this.startFunc.apply(this.startFunc, this.startParams.concat(this.currentCallback));
  }
}

this.startFunc是一个类似于函数(param1,param2,param3,callback)的函数我无法控制这个.startFunc,只是它会用一些参数调用回调。

问题

我有一个this.currentCallback,因为我需要能够取消回调。也就是说,我已经调用了this.startFunc,需要阻止回调。

问题是,MyObject可能会发送另一个回调(一次不会发送2个),但如果我不在需要的时候立即取消第一个回调,当我取回它们时,我就不知道哪一个是有效的!可能会让人困惑,所以这里有一个图表:

  • 发送回叫1次
  • 需要取消!取消此处的回调A
  • 发送回调2关闭(仍然说函数有回调1)

此时,如果我不取消A,那么当我收到回拨时,我就不知道是哪一个了。如果我取消了A,那么我知道是B,没人担心。

如果您不理解,请告诉我:)

注释中列出的方案的概念验证:为每个回调创建一个新的闭包,让回调确定它是否处于活动状态。

function foreignAPIThatStartsACallback(callback) {
  setTimeout(callback, 1000);
}
var activeCallback;
function wrapCallback(callback) {
  var args = Array.prototype.slice.call(arguments, 1);
  var that = this;
  var wrappedCallback = function() {
    if (wrappedCallback == activeCallback) {
      callback.apply(that, args);
    }
  }
  activeCallback = wrappedCallback;
  return wrappedCallback;
}
function myCallback(what, who) {
  console.log(who + " says " + what);
}
foreignAPIThatStartsACallback(wrapCallback(myCallback, "Hello", "Mario"));
foreignAPIThatStartsACallback(wrapCallback(myCallback, "Goodbye", "Luigi"));
// Mario is cancelled when Luigi gets started

具有多种可能的活动:

function foreignAPIThatStartsACallback(callback) {
  setTimeout(callback, 1000);
}
var activeCallbacks = {};
function wrapCallback(callback) {
  if (!wrapCallback.count) wrapCallback.count = 0;
  wrapCallback.count++;
  var args = Array.prototype.slice.call(arguments, 1);
  var that = this;
  var wrappedCallback = function() {
    if (wrappedCallback.id in activeCallbacks) {
      cancelCallback(wrappedCallback);
      callback.apply(that, args);
    }
  }
  wrappedCallback.id = wrapCallback.count;
  activeCallbacks[wrapCallback.count] = true;
  return wrappedCallback;
}
function cancelCallback(wrappedCallback) {
  delete activeCallbacks[wrappedCallback.id];
}
function myCallback(what, who) {
  console.log(who + " says " + what);
}

var marioCallback = wrapCallback(myCallback, "Hello", "Mario");
foreignAPIThatStartsACallback(marioCallback);
var luigiCallback = wrapCallback(myCallback, "Goodbye", "Luigi");
foreignAPIThatStartsACallback(luigiCallback);
var daisyCallback = wrapCallback(myCallback, "Mama?", "Peach");
foreignAPIThatStartsACallback(daisyCallback);
cancelCallback(luigiCallback);
// Mario and Daisy go off