javascript - 实现 Promise.all

标签 javascript promise

<分区>

exercises 之一在 Eloquent Javascript 这本书的第 17 章是实现 Promise.all() 方法,我想出了这个实现(不起作用):

function all(promises) {
  return new Promise(function(success, fail) {
    var successArr = new Array(promises.length);
    if (promises.length == 0)
      success(successArr);
    var pending = promises.length;
    for (var i = 0; i < promises.length; i++) {
      promises[i].then(function(result) {
        successArr[i] = result;
        pending -= 1;
        if (pending == 0)
          success(successArr);
      }, function(error) {
        fail(error);
      });
    }
  });
}


// Testing
function soon(val) {
  return new Promise(function(success) {
    setTimeout(function() { success(val); },
               Math.random() * 500);
  });
}
all([soon(1), soon(2), soon(3)]).then(function(array) {
  console.log("This should be [1, 2, 3]:", array);
});
// => [undefined, undefined, undefined, 3]

有趣的是,除了在我的例子中使用 forEach 来迭代 promises 数组而不是 for 循环之外,作者的解决方案是相似的:

function all(promises) {
  return new Promise(function(success, fail) {
    var successArr = new Array(promises.length);
    if (promises.length == 0)
      success(successArr);
    var pending = promises.length;
    promises.forEach(function(promise, i) {
      promise.then(function(result) {
        successArr[i] = result;
        pending -= 1;
        if (pending == 0)
          success(successArr);
      }, function(error) {
        fail(error);
      });
    });
  });
}

// Testing
function soon(val) {
  return new Promise(function(success) {
    setTimeout(function() { success(val); },
               Math.random() * 500);
  });
}
all([soon(1), soon(2), soon(3)]).then(function(array) {
  console.log("This should be [1, 2, 3]:", array);
});
// => [1, 2, 3]

为什么 forEach 的使用在这里造成了所有不同?我猜这与传递给 forEach 的匿名函数创建的范围有关,但我不太清楚它是如何工作的。

最佳答案

我刚刚弄明白了,它是 i 变量,因为我们在一个 for 循环中,它在 promise 有机会解析之前发生变化,但在 forEach 版本上 i 变量是正确的作用域,因此每次迭代都有自己的 i 变量

关于javascript - 实现 Promise.all,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36530897/

相关文章:

php - 来自 Canvas 的无效 base64 字符串

javascript - 图像未在 reactjs 中加载

javascript - 理解带有未捕获 promise 的消息

javascript - 如何删除MongoDB中的文档和所有嵌入文档?

javascript - 区分 AJAX 调用/浏览器请求

javascript - 异步关系上的 Ember 数据计算属性

javascript - 如何使用 Recast.ai 使用 message.addReply 添加来自基于 promise 的 API 调用的结果?

javascript - 同步操作DOM?

javascript - 如果我明确返回一个 Promise,我应该定义异步函数吗?

javascript - 无法让 Javascript 函数从 gridview 中的文本框触发