【问题标题】:Promise.all() and understanding when it resolvesPromise.all() 并理解它何时解决
【发布时间】:2017-01-21 09:14:09
【问题描述】:

我是 node.js 的新手,我正在编写一个需要对异步 API 调用做出承诺的程序。我有一个关于执行我在研究中偶然发现的示例代码的问题。

下面的代码(根据我的理解)将访问一个 API,等待响应,然后将该响应解析为一个 Promise。这是迭代完成的,每个创建的 Promise 都会传递到 Promise 数组中。最终 Promise.all() 会在 promise 数组上被调用,并且 .then() 更多代码将执行以遍历数组并将图像添加到页面中。

function getMovie(title) {
  return new Promise(function(resolve, reject) {
  var request = new XMLHttpRequest();

  request.open('GET', 'http://mymovieapi.com/?q=' + title);
  request.onload = function() {
    if (request.status == 200) {
    resolve(request.response); // we get the data here, so resolve the Promise
    } else {
      reject(Error(request.statusText)); // if status is not 200 OK, reject.
    }
  };

    request.onerror = function() {
      reject(Error("Error fetching data.")); // error occurred, so reject the Promise
    };

    request.send(); // send the request
 });
}

function fetchMovies() {
  var titles = document.getElementById('titles').value.split(',');
  var promises = [];

  for (var i in titles) {
    promises.push(getMovie(titles[i])); // push the Promises to our array
  }

  Promise.all(promises).then(function(dataArr) {
    dataArr.forEach(function(data) {
    var img = JSON.parse(data)[0].poster.imdb;

    document.getElementById('movies').innerHTML =      document.getElementById('movies').innerHTML + '<img src="' + img + '"/>';
    });
  }).catch(function(err) {
    console.log(err);
  });
};
fetchMovies();

我在这里不明白的是 Promise.all() 如何等待所有 API 响应被推送到 Promise 中。由于 getMovie(title) 在将每个 Promise 推入 Promise 数组之前将其解析,因此不应该是第一个已解决的 Promise 被推入会导致 Promise.all() 部分执行(作为 1 of 1 Promise in数组已解析)?

【问题讨论】:

  • Promise.all(promises) 行被调用了多少次?当它发生时,它的参数数组中有多少项?回答这些问题,你就会豁然开朗。 )
  • 我认为你误解了承诺的作用。立即创建承诺对象,并通过 thenable 将闭包传回。链的调用是同步发生的——但是解析一个接一个地进行评估。在 all 中 - 添加到集合中的每个承诺都会在解决时评估集合的状态。当它们全部解决时,状态将转换为已解决状态,并且数组的内容——第一个 getMedia 函数的结果——被传入。
  • 嗨,斯科特,如果你了解猫鼬,也许这个链接可能会有所帮助stackoverflow.com/questions/39470090/…

标签: javascript node.js


【解决方案1】:

我认为混淆出现在您说“因为getMovie(title) 在将每个承诺推入promises 数组之前解析每个承诺”。

这不是正在发生的事情。注意返回语句。 getMovie 函数立即返回一个Promise 对象,并在稍后(通常)调用resolve(或reject)函数时进行解析,在这种情况下是在异步调用之后。

所以它首先返回一个 Promise,然后这个 Promise 稍后解决(或拒绝)。而Promise.all 等待这些承诺的数组得到解决。

【讨论】:

    【解决方案2】:

    当您调用Promise.all 时,数组已被Promise 对象填充。 Promise.all 相当于在所有承诺上调用 .then。当所有的承诺都解决了,或者有一个被拒绝时,你的处理程序就会被调用。

    【讨论】:

      猜你喜欢
      • 2016-01-09
      • 2015-08-25
      • 2015-02-10
      • 2019-03-11
      • 2020-06-23
      • 2022-08-20
      • 2022-10-26
      • 1970-01-01
      相关资源
      最近更新 更多