【问题标题】:Implementing Promise.all [duplicate]实施 Promise.all [重复]
【发布时间】:2016-04-10 14:17:55
【问题描述】:

Eloquent Javascript 一书第 17 章的exercises 之一是实现 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 的匿名函数创建的范围有关,但我不太清楚它是如何工作的。

【问题讨论】:

  • @Bergi 这个问题不是重复的,至少不是你标记为重复的原始问题
  • @AlexMills:怎么会这样?问题是异步回调中i 变量的值,这正是规范的欺骗目标所描述的。即使是OP的自我回答也表明了同样的观点。你会有什么不同的回答?

标签: javascript promise


【解决方案1】:

我刚刚想通了,它是 i 变量,因为我们在一个 for 循环中,它在 promise 有机会解决之前发生了变化,但是在 forEach 版本中,i 变量的范围是正确的,所以每次迭代都有它是自己的i 变量

【讨论】:

  • 没错!好眼力。这被称为闭包——我认为你的书没有解释它,但你会非常了解它们。有关说明,请参阅 this question
  • 感谢您的链接 ;)
猜你喜欢
  • 2014-07-01
  • 2012-02-19
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 2022-12-18
  • 2021-12-12
  • 1970-01-01
相关资源
最近更新 更多