我正在使用一个使用jQuery Deferred Objects的框架。
在我的代码中,应该成功执行一个异步操作,以便执行另一个异步操作。
function doOperation() {
var def2mock = $.Deferred();
var def1 = doSomeAsyncOperation().done(function () {
var def2 = doAnotherAsyncOperation();
});
return $.when(def1, def2mock);
}
所以我把第二个操作的调用放在第一个操作延迟的“完成”承诺中,如例子中所示。
现在,我用函数doOperation
包装这个序列。 doOperation
的结果应该是两个异步调用的延迟的连接。如果所有异步操作都成功则意义doOperation
成功,如果其中任何异步操作失败,则失败,这正是$.when
所做的。
问题是为了使用$.when
创建联接,我需要调用$.when
时出现的延迟。并且因为此时第二个异步操作的延迟不可用,所以我必须首先找到创建连接的方法,然后将延迟的第二个异步操作添加到连接以后。 / p>
为此,我想我可以在$.Deferred
中定义名为def2
的新模拟 doOperation
。当真正的def2
准备就绪时,我可以某种方式链接真实的延迟到模拟的一个,即使真实的一个与模拟一个同步它的状态。我找到的唯一方法是做
def2.done(def2mock.resolve)
// and
def2.fail(def2mock.reject)
但我不认为这种手动链接是正确的方法。
所以请告诉我你是否有更好的建议如何以正确的方式做到这一点。
答案 0 :(得分:2)
当真正的
def2
准备就绪时,我可以某种方式链接真实延迟到模拟的那个,即使真实的一个与模拟一个同步。
这实际上是.then
的作用:它返回一个新的promise,当从传递的回调中返回的promise被解析/拒绝时,它会被解析/拒绝。
为了使这项工作与$.when
一致,您必须保留对原始承诺的引用:
function doOperation() {
var def1 = doSomeAsyncOperation();
var def2 = def1.then(function () {
return doAnotherAsyncOperation();
});
return $.when(def1, def2);
}
当回调返回的承诺被解析时, def2
将被解析,即doAnotherAsyncOperation
返回的承诺。
但我不认为从概念的角度来看,使用$.when
是一个不错的选择。您实际上正在执行顺序两个异步函数,但$.when
用于在 parallel 中运行异步函数。
我只是通过.then
链接函数调用并收集响应:
function doOperation() {
return doSomeAsyncOperation().then(function (resp1) {
return doAnotherAsyncOperation().then(function(resp2) {
return [resp1, resp2];
});
});
}
我会说doAnotherAsyncOperation
之后执行doSomeAsyncOperation
更加清晰,doOperation
的来电者可以使用这两个来电的结果。
你可能必须为失败案例做类似的事情。
答案 1 :(得分:1)
我对Deferred没有任何经验(我也不完全理解它的作用),但是如果你只是想进行连锁操作,那会是这样吗?
function doOperation(operations) {
var wrapper = {};
wrapper.index = 0;
wrapper.operations = operations;
wrapper.onthen = $.proxy(function() {
if (this.index < this.operations.length) {
this.operations[this.index]().then(this.onthen);
}
this.index++;
}, wrapper);
wrapper.onthen();
}