我正在尝试对async的瀑布函数进行逆向工程,以便更好地理解它是如何工作的 虽然我提出了以下主要工作的代码,但它有一个我无法解释的奇怪行为:传递给下一个函数的参数似乎在某处丢失,被浏览器中的load事件和节点中的require函数所取代。
我的代码:
const waterfall = (callbacks, callback) => {
callback = callback || function() {
};
let counter = 0,
errors = [],
results = [],
nextExecutor = (err, res) => {
let argsArray = Array.from(arguments),
error = (argsArray.length >= 2 && !!argsArray[ 0 ]
? argsArray[ 0 ]
: false
),
result = (error
? argsArray[ 1 ]
: argsArray[ 0 ]
),
currentIteration = counter++,
currentNextExecutor = (counter === callbacks.length
? () => {
}
: nextExecutor
);
if (error !== false) {
errors.push(error);
}
results.push(result);
callbacks[ currentIteration ].call(
{},
currentNextExecutor,
result
);
if (counter === callbacks.length) {
callback.call(
{},
(errors.length > 0
? errors[ 0 ]
: null
),
results
);
}
};
callbacks[ counter++ ](nextExecutor);
};
waterfall([
function(next) {
console.log('hi! this is first.');
setTimeout(() => {
next(null, 10);
}, 200);
},
function(next, x) {
console.log('hi! this is second: ' + x);
setTimeout(() => {
next(null, x);
}, 200);
},
function(next, x) {
console.log('hi! this is third: ' + x);
x++;
setTimeout(() => {
next(null, x);
}, 200);
},
function(next, x) {
console.log('hi! this is last.');
setTimeout(() => {
next(null, x);
}, 200);
}
], (error, results) => {
console.log('Error: ' + JSON.stringify(error));
console.log('Results: ' + JSON.stringify(results));
});
预期产出:
hi! this is first.
hi! this is second: 10
hi! this is third: 10
hi! this is last.
Error: null
Results: [ 10, 10, 11, 11]
实际输出:
hi! this is first.
hi! this is second: function require(path) { ... }
hi! this is third: function require(path) { ... }
hi! this is last.
Error: {}
Results: [null,null,null]
我不明白哪里出错了 - arguments
对象没有传递值的引用。
注意:这不是为了模仿异步源代码,因为我还没有看过它。我想出于学习目的自行解决问题。
答案 0 :(得分:0)
由于箭头函数不绑定自己的arguments
变量,因此我使用的是父作用域arguments
。其中,最重要的是浏览器中的load
事件或节点中的require
。
解决了这个问题 - 有趣的是,使用箭头功能不能按预期工作,但我不知道为什么。将nextExecutor
的声明交换为标准函数(并重构参数处理一下)似乎解决了这个问题。
因此,nextExecutor
代码如下所示:
nextExecutor = function(error, result) {
let currentIteration = counter++,
currentNextExecutor = (counter === callbacks.length
? function() {}
: nextExecutor
);
if (!!error) {
errors.push(error);
}
results.push(result);
callbacks[ currentIteration ].call(
{},
currentNextExecutor,
result
);
if (counter === callbacks.length) {
callback.call(
{},
(errors.length > 0
? errors[ 0 ]
: null
),
results
);
}
};
callbacks[ counter++ ](nextExecutor);
};
答案 1 :(得分:0)
那么你的问题就在这里
result = (error
? argsArray[ 1 ]
: argsArray[ 0 ]
),
由于错误始终为false,因此结果为args [0],它始终为null?
argsArray [索引]换句话说就是......