因此,我正在编写一个函数,它会产生一堆数据库调用。我想将它们的结果存储在一个数组中,并在完成后触发回调。无嵌套函数的javascript回调跟踪完成
一些伪代码可以帮助:
function getStuff (array, callback) {
var results = [];
var done = 0;
for (var i = 0, len = array.length; i < len; i++) {
database.fetchOne(array[i], function(result) {
results[i] = result;
done++;
if (done == len)
callback(results);
});
}
}
这个伟大的工程。但是,我被告知将闭包嵌套在循环中是一种不好的做法,因为它会在每次迭代中定义函数,并且会导致性能成本。
其他答案建议把回调的循环之外:
function getStuff (array, callback) {
var results = [];
var done = 0;
for (var i = 0, len = array.length; i < len; i++) {
database.fetchOne(array[i], myCallback.bind(this, i, results, done, callback));
}
}
function myCallback (i, results, done, callback, result) {
results[i] = result;
done++;
if (done == len)
callback(results);
}
但是,这并不工作,因为done
有一个不变的类型,所以它不getStuff
改变done
值。
那么...我该怎么办?
讨厌的情况下,为了澄清,“完成”不是不可变的类型,它是一个通过价值传递而非通过引用传递的原语。这是一个很好的区别,但我认为重要的是要注意。 –
你在什么环境?这是node.js?你可以通过使用承诺和执行回调来实现这一点,它应该是一个更优雅的处理方式。 – Sosdoc
@Sosdoc,没关系。在node.js和客户端JS中,同样的异步回调标准也适用。 –