【发布时间】:2015-10-01 01:36:38
【问题描述】:
所以我正在编写一个进行大量数据库调用的函数。我想将他们的结果存储在一个数组中,并在完成后触发回调。
一些伪代码可能会有所帮助:
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 的值。
那么……我该怎么办?
【问题讨论】:
-
澄清一下,
done不是不可变类型,它是一个通过值而不是通过引用传递的原语。这是一个很好的区别,但我认为需要注意这一点。 -
你在什么背景下?这是 node.js 吗?您可以通过使用承诺并在所有完成后执行回调来解决此问题,这应该是一种更优雅的处理方式。
-
@Sosdoc,没关系。在 node.js 和客户端 JS 中,异步回调的标准相同。
-
@PatrickRoberts 我只是要求指出一个使用 Promise 的可能解决方案,以防这不是节点(但我怀疑)它可以通过使用 jquery 来完成。
-
@Sosdoc 我在节点中。
标签: javascript node.js callback closures