这是我在接受采访时提出的一个问题。我知道数组只会返回零,因为这是异步的,但是为什么会发生这种情况,以及如何修复它以便结果数组插入适当的数据?
问题:假设findData是一个接受查询对象并返回查询结果的承诺的函数。假设someRandomArrayOfQueries是一个查询对象数组。解释以下代码将打印的内容以及原因:
function runMultipleQueries(queries) {
var results = [];
queries.forEach(doQuery);
return results;
function doQuery(query) {
findData(query)
.then(results.push.bind(results));
}
}
function log(value) {
console.log(value);
}
runMultipleQueries(someRandomArrayOfQueries).forEach(log);
答案 0 :(得分:1)
doQuery
将在以后的某个时间点执行。然而,该数组会立即返回并记录。因此,该数组仍为空,并且没有记录任何内容。
要修复此runMultipleQueries
,还需要返回一个承诺。这可能是例如看起来像这样。
function runMultipleQueries(queries) {
return Promise.all(queries.map(findData));
}
function log(value) {
console.log(value);
}
runMultipleQueries(someRandomArrayOfQueries).then(function(results) {
results.forEach(log);
});
如果你想保持runMultipleQueries
与原版相似,你也可以像这样创建一个新的Promise,但这会不必要地复杂。
function runMultipleQueries(queries) {
return new Promise(function(resolve, reject) {
var results = [];
queries.forEach(doQuery);
function doQuery(query) {
findData(query)
.then(function(result) {
results.push(result);
if(results.length === queries.length) resolve(results);
}, reject);
}
});
}
您也可以在doQuery
内记录结果,但是您无法保证记录结果的顺序。这也会使你在登录后对这些结果做任何其他事情变得更加困难。
function runMultipleQueries(queries) {
queries.forEach(doQuery);
function log(value) {
console.log(value);
}
function doQuery(query) {
findData(query)
.then(log);
}
}
runMultipleQueries(someRandomArrayOfQueries);