我试图按顺序执行以下函数(同步/异步)数组(避免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);
});Run Code Online (Sandbox Code Playgroud)
您的函数链接取决于对k(). 因此在你的缓存逻辑中:
if (cache[f]) {
return;
} else {
// ...
Run Code Online (Sandbox Code Playgroud)
链条断了。
你想要的是这样的:
if (cache[f]) {
return k();
} else {
// ...
Run Code Online (Sandbox Code Playgroud)
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
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,使用此结构实现任何流逻辑都相当容易。通过控制如何跟踪结果以及每次迭代从数组中删除的函数数量,我们可以轻松实现瀑布、parallelLimit 等功能。
| 归档时间: |
|
| 查看次数: |
166 次 |
| 最近记录: |