Javascript采访承诺

时间:2015-06-27 16:14:03

标签: javascript promise

这是我在接受采访时提出的一个问题。我知道数组只会返回零,因为这是异步的,但是为什么会发生这种情况,以及如何修复它以便结果数组插入适当的数据?

问题:假设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);

1 个答案:

答案 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);