这是我的问题的简化版本:
var callback_one = function (result_from_web_service) {
console.log('callback one');
};
var callback_two = function (result_from_web_service) {
console.log('callback two');
};
// the async_calls are library calls that i don't own or modify
var x = function () {
console.log('x is called');
async_call_one(callback_one);
async_call_two(callback_two);
};
var y = function () {
console.log('y is called');
};
Test:
x();
y();
// prints: 'x is called', 'y is called', 'callback one', 'callback two'
// what i need: 'x is called', 'callback one', 'callback two', 'y is called'
我所做的就是在 call_back_two 中调用 y():
var callback_two = function (result_from_web_service) {
console.log('callback two');
y();
};
但现在我的用例要求在回调之外调用 y(将由我的代码的用户调用)。即 x() 和 y() 的调用是独立的,x() 的调用不会最终调用 y()。 y() 应该被独立调用,但前提是 x() 及其回调被处理。将 x() 视为在 java 中创建一个对象,将 y() 视为您可以随时调用的方法。
//.. some code, x() does some kind of initialization...
x();
// OPTIONALLY call y(), but make sure x() and its callbacks are processed
y();
我尝试了以下方法,但没有用。
$.when(x()).then(y());
谢谢,
最佳答案
使类似这样的东西正常工作的唯一方法是使 y
异步。基本上,y
在执行自己的代码之前会在内部等待 x
完成。这类似于 domready
或 onload
之类的东西,它们在执行自己的逻辑之前等待其他事情发生。
有两种方法可以做到这一点。第一种最简单也是最天真的方法是 setTimeout
轮询。让 x
设置一个变量或属性并在执行前检查:
function y () {
if (x.ready) {
/* do what you need to do here */
}
else {
setTimeout(y,100);
}
}
第二种方法是创建虚拟事件或 promise 。并非所有 promise 库都支持使用已经过期的 promise (我自己自制的),因此您可能需要编写自己的控制流来处理这种情况。为此,您需要重写 x
以支持事件或类似 promise 的 api:
var x = (function () {
var async_calls = 2;
var callback;
f = function () {
console.log('x is called');
async_call_one(function(){
async_calls --;
if (async_calls == 0 && callback) callback();
callback_one();
});
async_call_two(function(){
async_calls --;
if (async_calls == 0 && callback) callback();
callback_two();
});
}
f.loaded = function (loaded_callback) {
callback = loaded_callback;
if (async_calls == 0) callback();
}
return f;
})();
现在在 y
中,您可以使用 x.loaded
函数在加载 x 时执行您的代码:
function y () {
x.loaded(function(){
/* do what you need to do here */
});
}
当然,这有让y
异步的问题。因此,如果您的用户希望编写如下内容:
y();
a();
b();
然后 a
和 b
可能会或可能不会在 y
之前执行。要解决这个问题,您需要让 y
接受回调,以便您的用户可以控制他们的程序流程:
function y (callback) {
if (x.ready) {
/* do what you need to do here */
callback();
}
else {
setTimeout(function(){y(callback)},100);
}
}
或:
function y (callback) {
x.loaded(function(){
/* do what you need to do here */
callback();
});
}
所以他们必须像这样使用 y
:
y(function(){
a();
b();
});
或者,如果您喜欢那种风格,您可以让 y
返回一个 promise。
关于javascript - 在返回另一个函数的回调后调用一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24540104/