我正在尝试按顺序执行以下函数(同步/异步)数组(避免callbackHell),实现函数runCallbacksInSequence
(我需要实现自己的函数来了解回调的工作原理并避免使用 Async.js)。
这是我到目前为止所拥有的。功能runCallbacksInSequence
效果很好,直到达到相同的效果callback
不止一次。它停止并且不继续执行下一个回调。理想情况下,如果它得到相同的callback
不止一次,不应执行第二次并继续下一个callback
.
如果您有任何想法,请告诉我我做错了什么以及如何解决它。- 没有承诺和异步/等待
function first(cb) {
setTimeout(function() {
console.log('first()');
cb(null, 'one');
}, 0);
}
function second(cb) {
setTimeout(function() {
console.log('second()');
cb(null, 'two');
}, 100);
}
function third(cb) {
setTimeout(function() {
console.log('third()');
cb(null, 'three');
}, 0);
}
function last(cb) {
console.log('last()');
cb(null, 'lastCall');
}
const cache = {};
function runCallbacksInSequence(fns, cb) {
fns.reduce(
function(r, f) {
return function(k) {
return r(function() {
if (cache[f]) {
return;
// f(function(e, x) {
// e ? cb(e) : k(x);
// });
} else {
cache[f] = f;
return f(function(e, x) {
return e ? cb(e) : k(x);
});
}
});
};
},
function(k) {
return k();
}
)(function(r) {
return cb(null, r);
});
}
const fns = [first, second, third, second, last];
runCallbacksInSequence(fns, function(err, results) {
if (err) return console.log('error: ' + err.message);
console.log(results);
});
您的函数链取决于对k()
。因此在你的缓存逻辑中:
if (cache[f]) {
return;
} else {
// ...
链条断了。
你想要的是这样的:
if (cache[f]) {
return k();
} else {
// ...
替代实施
嵌套函数实现的问题之一是,由于多个嵌套作用域(并且同时处理多个函数),因此很难推理(r
, f
, k
, cb
).
一个更简单的方法是,您可以使用队列来代替尝试以编程方式构建回调地狱(这就是 async.js 所做的)。这个想法很简单,pop() 或 shift() 从数组中执行函数,直到数组为空:
function runCallbacksInSequence(fns, cb) {
let result = [];
let cache = {};
function loop () {
if (fns.length > 0) {
let f = fns.shift(); // remove one function from array
if (cache[f]) {
loop(); // skip this round
return;
}
cache[f] = f;
f(function(err, val) {
if (!err) {
result.push(val); // collect result
loop();
}
else {
// Handle errors however you want.
// Here I'm just terminating the sequence:
cb(err, result);
}
});
}
else {
cb(null, result); // we've collected all the results!!
}
}
loop(); // start the loop
}
正如您所看到的,使用此结构实现任何流逻辑都相当容易。通过控制如何跟踪结果以及每次迭代从数组中删除的函数数量,我们可以轻松实现瀑布、parallelLimit 等功能。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)