在 javascript 中取消回调
Cancel a callback in javascript
我有类似的东西:
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 是一个类似于 function(param1, param2, param3, callback) 的函数
我无法控制 this.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
我有类似的东西:
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 是一个类似于 function(param1, param2, param3, callback) 的函数 我无法控制 this.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