关于承诺的Javascript采访

关于承诺的Javascript采访,javascript,promise,Javascript,Promise,这是我在采访中被问到的一个问题。我知道数组将只返回零,因为这是异步的,但为什么会发生这种情况,以及如何修复它以使结果数组插入适当的数据 问题:假设findData是一个接受查询对象并返回查询结果承诺的函数。还假设someRandomArrayOfQueries是一个查询对象数组。解释以下代码将打印什么以及为什么: function runMultipleQueries(queries) { var results = []; queries.forEach(doQuery); retur

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

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

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
与原来的类似,您也可以创建这样的新承诺,但这将是不必要的复杂

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

你确定这是普通的JavaScript吗?你需要阅读异步过程JavaScript。重要的是,你不知道时间会是什么时候。承诺不会阻碍这个过程。承诺只是一种承诺,当他拥有数据时,他将在其中执行代码,或者在catch中执行错误。返回函数将在任何时候执行,因为javascript进程将继续执行代码行。@PaulS。代码看起来不错。我想我们假设在这种情况下findData(查询)需要很长时间,因为他们试图测试您对单线程javascript的了解。我是否可以通过在promise中添加控制台日志来修复它?你能做到吗?你能做到-我又加了一个例子。但我建议不要这样做。