我试图按顺序执行函数(sync / async)的以下数组(避免callbackHell),实现函数tf.cond
(我需要实现自己的函数以了解回调的工作原理并避免使用Async.js)。
这是我到目前为止所拥有的。函数runCallbacksInSequence
运作良好,直到多次获得相同的runCallbacksInSequence
为止。它停止并且不再继续执行下一个回调。理想情况下,如果它多次获得相同的callback
,则不应第二次执行它,而继续下一个callback
。
如果您有任何想法,请告诉我我做错了什么以及如何解决。 -没有承诺和异步/等待
callback
答案 0 :(得分:2)
您的函数链接取决于对k()
的调用。因此,在您的缓存逻辑中:
if (cache[f]) {
return;
} else {
// ...
链条断裂。
您要的是这个:
if (cache[f]) {
return k();
} else {
// ...
嵌套函数实现的问题之一是,由于存在多个嵌套作用域(并且多个函数被同时处理(r
,f
,{{1} },k
。
更简单的方法不是尝试以编程方式构建回调地狱,而是可以使用队列(async.js就是这样做的)。这个想法很简单,可以从数组开始直到数组为空的pop()或shift()函数:
cb
如您所见,使用这种结构很容易实现任何流逻辑。通过控制跟踪结果的方式以及每次迭代从数组中删除多少个函数,我们可以轻松实现诸如Waterfall,parallelLimit等功能。
答案 1 :(得分:1)
我想在基于缓存的实现中,您可以通过直接wsimport -keep -p com.samlpe.jaxws.client -extension <WSDL URL>
调用来省略加倍的步骤。
k()
想法:
return;
if (cache[f]) {
return;
// f(function(e, x) {
// e ? cb(e) : k(x);
// });
答案 2 :(得分:1)
您的代码对我来说有点难读。所以这是替代解决方案:
<script>
// The data
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 fns = [first, second, third, second, last];
// We need hash function to create the identifyer of the function
function hashCode(str) {
return Array
.from(str)
.reduce((s, c) => Math.imul(31, s) + c.charCodeAt(0) | 0, 0);
}
const cache = [];
function reducer(accumulator, currentFunction) {
// Take the functon string representation to detect "the same function"
const hash = hashCode(currentFunction.toString());
// Process the result of the current function and call the next one.
// We use "reduceRight" so `accumulator` is the next function in the chain.
const cb = function (fp, result) {
console.log(result);
// Cache the result;
cache[hash] = result;
accumulator();
}
// Run just a callback if we already have the result of the current function
return () => cache[hash] ? cb(null, cache[hash]) : currentFunction(cb);
}
fns.reduceRight(reducer, () => { })();
</script>
结果:
first()
one
second()
two
third()
three
two
last()
lastCall
如果您根本不想处理缓存的结果,则将对回调的调用替换为直接对累加器的调用。
return () => cache[hash] ? cb(null, cache[hash]) : currentFunction(cb);
替换为:
return () => cache[hash] ? accumulator() : currentFunction(cb);
结果:
first()
one
second()
two
third()
three
last()
lastCall
没有缓存的解决方案
它更干净:
<script>
// Use the same data as in the example with cache
function reducer(accumulator, currentFunction) {
const cb = function (fp, result) {
console.log(result);
accumulator();
}
return () => currentFunction(cb)
}
fns.reduceRight(reducer, () => { })();
</script>
结果:
first()
one
second()
two
third()
three
second()
two
last()
lastCall