我可以像下面这样一个接一个地执行异步函数:
function asyncFn(e, cb) {
return new Promise((res, rej) => {
setTimeout(() => {
console.log(e);
res();
}, 1000);
});
}
var arr = [1,2,3,4,5];
arr.reduce(
(chain, e) => chain.then(()=>asyncFn(e)),
Promise.resolve()
);
是否可以使用回调而不是解决诺言来做同样的事情?
答案 0 :(得分:-2)
当然可以,但是要复杂一些:
const logLater = (msg, time, cb) => setTimeout(() => (console.log(msg), cb()), time);
const arr = [1, 2, 3, 4, 5];
arr.reduceRight((next, el) => () => logLater(el, 1000, next), () => console.log("all done!"))();
或多行:/:
function logLater(msg, time, cb) {
setTimeout(function() {
console.log(msg);
cb();
}, time);
}
const arr = [1, 2, 3, 4, 5];
arr.reduceRight(function(next, el) {
return function current() {
logLater(el, 1000, next);
};
}, function() { })();
建立回调链的过程是向后的,因此记录5
将被包装在一个函数中,该函数将在调用时进行记录,然后将该函数传递到4
的包装器中,该包装器将在调用时进行调用记录了4
,4
的包装将作为next
传递到3
的包装,依此类推。
但是,如果您只想对数组的所有元素执行某项任务并等待上一个回调,则可以使用一个调用自身的函数来做到这一点:
function logLater(msg, time, cb) {
setTimeout(function() {
console.log(msg);
cb();
}, time);
}
const arr = [1, 2, 3, 4, 5];
(function next(i) {
logLater(arr[i], 1000, function done() {
if(i < arr.length - 1) next(i + 1);
});
})(0);