遵循此示例
Dojo FAQ: How can I sequence asynchronous operations?
function doNext(previousValue) {
var dfd = new Deferred();
// perform some async logic; resolve the promise
setTimeout(function () {
var next = String.fromCharCode(previousValue.charCodeAt(previousValue.length - 1) + 1);
dfd.resolve(previousValue + next);
}, 50);
return dfd.promise;
}
var promise = doNext('a');
for (var i = 0; i < 9; i++) {
promise = promise.then(doNext);
}
promise.then(function (finalResult) {
// 'doNext' will have been invoked 10 times, each
// invocation only occurring after the previous one completed
// 'finalResult' will be the value returned
// by the last invocation of 'doNext': 'abcdefghijk'
console.log(finalResult);
});
如何摆脱循环 - 即当doNext满足某个标准时停止处理后续的doNext函数调用 - 例如当下一个字符是&#39; d&#39;并将计算值返回到该点?
编辑:到目前为止,我尝试使用deferred cancel()方法,但它只是杀死了进程,并且什么也没有返回。
setTimeout(function () {
var next = String.fromCharCode(previousValue.charCodeAt(previousValue.length - 1) + 1);
if(previousValue + next == 'abc')
dfd.cancel('abc');
else
dfd.resolve(previousValue + next);
}, 50);
答案 0 :(得分:1)
您可以通过检查promise中返回的值来决定是否再次调用异步请求。这与您在break
循环中添加for
不同。但结果将是你想要的。
将调用所有9个promise.then
,但doNext
将不会被调用9次。以下是相同的片段。
for (var i = 0; i < 9; i++) {
promise = promise.then(function(val){
return val === "abcd" ? val : doNext(val);
});
}
您可能认为这不存在循环。这是因为在调用回调函数之前循环已经完成。但是,回调函数只是返回值,而不是调用异步函数。这导致循环快速完成。下面是一个链接到JSBin,我已经增加了超时,你会看到,最初需要更多的时间,直到返回所需的结果然后快速退出。
https://jsbin.com/qiwesecufi/edit?js,console,output
另一个可以进行检查的地方是doNext
函数本身。
function doNext(previousValue) {
var dfd = new Deferred();
if(previousValue === "abcd")
return previousValue;
// perform some async logic; resolve the promise
setTimeout(function () {
var next = String.fromCharCode(previousValue.charCodeAt(previousValue.length - 1) + 1);
dfd.resolve(previousValue + next);
}, 1000);
return dfd.promise;
}
希望这有用。
答案 1 :(得分:1)
当您总是想要处理所有项目(或同步决定您需要的项目数量)时,您应该只使用reduce
(或promise = promise.then(doNext)
)循环方法。
要循环任意次数并在任何步骤中突破,递归是更好的方法:
function wait(t, v) {
var dfd = new Deferred();
// asynchronously resolve the promise
setTimeout(function () {
dfd.resolve(v);
}, t);
return dfd.promise;
}
function doNext(previousValue) {
var next = String.fromCharCode(previousValue.charCodeAt(previousValue.length - 1) + 1);
return wait(50, previousValue + next);
}
function loop(v, i) {
if (i <= 0) return when(v);
if (v == "abc") return when("abc");
return doNext(v).then(function(r) {
return loop(r, i-1);
});
}
loop('a', 9).then(function (finalResult) {
console.log(finalResult);
});