如何等待在forEach循环中添加到数组的所有promise?

时间:2017-12-06 21:33:04

标签: javascript promise

我希望我的函数返回promises数组。函数内部的代码是异步的。我需要检查每个元素的类型并进行一些处理。我不知道该函数如何能够返回所有的promises - 一旦它完成了异步处理。 JSFiddle

function addFeatures (input) {

  var result = [];
  input.forEach(function (el) {

    if (Number.isInteger(el)) {
      // placeholder asynchronous
      setTimeout(function () {
        result.push(
          new Promise(function (resolve, reject) {
            resolve(el.toString() + 'string')
          })
        )
      }, 2000);
    } 
    else {
      // placeholder synchronous
      result.push(
        new Promise(function (resolve, reject) {
          resolve(el + 'string')
        }));
    }
  })
  return result;
};

var arr = [1, 'text']
var final = addFeatures(arr)
// should log 2 promises but logs only 1 - the synchronous
console.log(final)

2 个答案:

答案 0 :(得分:2)

重要的是立即创建承诺并在中执行异步内容

function addFeatures (input) {
  var result = [];
  input.forEach(function (el) {
    result.push(new Promise(function (resolve, reject) {
      if (Number.isInteger(el)) {
        // placeholder asynchronous
        setTimeout(function () {
          resolve(el.toString() + 'string')
        }, 2000);
      } else {
        // placeholder synchronous
        resolve(el + 'string')
      }
    });
  });
  return result;
}

我还建议使用map代替forEach + push

答案 1 :(得分:1)

根据Bergi的优秀答案,这是我的贡献:

1-功能addFeaturesarray.map

function addFeatures (input) {
    return input.map(function(el) {
        return new Promise(function (resolve, reject) {
            if (Number.isInteger(el)) {
                setTimeout(resolve, 2000, el.toString() + 'string');
                /* setTimeout(reject, 2000, el.toString() + 'string'); //for reject */
            }
            else {
                resolve(el + 'string');
                /* reject(el + 'string'); //for reject */
            }
        })
    });
};

2-用于测试addFeatures的结果的函数。

如果您没有正确管理上述代码的答案,有时 resolve中的asynchronous placeholder promise成为{{1} }并返回pending。这就是您需要undefined

的原因
Promise.all

3-调用上面的功能

function foo(){
    return Promise.all(addFeatures([1, 'text'])).then(values => {
        return values;
    }, function() {
        throw 'Promise Rejected';
    });
}

Fiddle