繁体   English   中英

数组充满未完成的承诺?

[英]Array filling up with Pending Promises?

我非常接近完成此功能的基础,但是我被困住了,这与我对诺言的缺乏了解有关,我正在学习它们的功能,等等。关于我的问题,我正在遍历当时的一些数据被存储在一个数组中,该数组将通过promise链传递给另一个函数,但是该数组中充满了待处理的promise,我只需要将promise中的实际数据放入数组中,请查看以下内容以了解发生了什么:

var getGameData = function(matchIdArray) {
var promise = new Promise(function(resolve,reject) {
  console.log('Start getGameData');
  s3.headObject({Bucket: 'lolsearchgames', Key: '347341'}, function(err, result) {
    console.log('Checking Bucket');
    if (err && err.code === 'NotFound') {
      console.log('Bucket data Not Found!')
      var gameData = new Array();
      for (var i = 0; i < matchIdArray.length; i++) {
        gameData.push(new Promise(function(res, rej) {
          lolapi.Match.get(matchIdArray[i], function (error, gamedata) {
            if (error) {
                rej(error);
            }
            if (gamedata) {
                console.log('Pushing new data to Array! ' + gamedata.matchId);
                res(gamedata);
            }
          })
        }));
      }
      if (gameData.length === 10) {
          console.log(gameData);
          resolve(gameData);
      }
    } else {
      console.log('Bucket data Found!');
    }
  })
});
return promise;
console.log('End getGameData');
};

使用Promise.all来等待所有的“ gameData”,如下所示-还可以使用Array#map避免推送到数组

注意:但是,如果在任何lolapi.Match.get承诺中有任何拒绝,Promise.all都会拒绝-这可能不是您想要的,我不确定您的代码示例

var getGameData = function getGameData(matchIdArray) {
  var promise = new Promise(function (resolve, reject) {
    console.log('Start getGameData');
    s3.headObject({ Bucket: 'lolsearchgames', Key: '347341' }, function (err, result) {
      console.log('Checking Bucket');
      if (err && err.code === 'NotFound') {
        console.log('Bucket data Not Found!');
        Promise.all(matchIdArray.map(function(matchId) {
          return new Promise(function (res, rej) {
            lolapi.Match.get(matchId, function (error, gamedata) {
              if (error) {
                rej(error);
              }
              res(gamedata);
            });
          })
        }))
        .then(resolve)
        .catch(reject);
      } else {
        console.log('Bucket data Found!');
        reject('Bucket data Found!');
      }
    });
  });
  console.log('End getGameData');
  return promise.then(function (results) {  // see note below
    return results.filter(function (result) {
      return result;
    });
  });
};

另类-我认为“整理”代码

var getGameData = function getGameData(matchIdArray) {
    return new Promise(function(resolve, reject) {
        console.log('Start getGameData');
        s3.headObject({
            Bucket: 'lolsearchgames',
            Key: '347341'
        }, function(err, result) {
            console.log('Checking Bucket');
            if (err && err.code === 'NotFound') {
                console.log('Bucket data Not Found!');
                resolve();
            } else {
                console.log('Bucket data Found!');
                reject('Bucket data Found!');
            }
        });
    }).then(function() {
        return Promise.all(matchIdArray.map(function(matchId) {
            return new Promise(function(res, rej) {
                lolapi.Match.get(matchId, function(error, gamedata) {
                    if (error) {
                        rej(error);
                    }
                    res(gamedata);
                });
            })
        }));
    }).then(function (results) {  // see note below
        return results.filter(function (result) {
            return result;
        });
    });
}

如果你使用蓝鸟的承诺,它有实用的方法来“promisify”节点回调风格的功能-在下面的代码, s3.headObjectAsync是的promisified版本s3.headObjectlolapi.Match.getAsync是的promisified版本lolapi.Match.get

您会看到,使用bluebirds promisify(和ES2015 +箭头表示法,因为您正在使用节点)使代码紧凑得多

var getGameData = function getGameData(matchIdArray) {
    return s3.headObjectAsync({
        Bucket: 'lolsearchgames',
        Key: '347341'
    })
    // do some gymnastics, because if there's no error, that should reject
    // but if the error is "NotFound" that should resolve
    .then(results => {
        throw {code: 'Bucket data Found!'};
    })
    .catch(err => {
        if (err && err.code === "NotFound") {
            return; // this is OK
        }
        throw err;
    })
    .then(() => Promise.all(matchIdArray.map(matchId => lolapi.Match.getAsync(matchId))))
    .then(results => results.filter(result => result)); // see note below
}

在ES5代码中,上面的代码仍然非常紧凑

var getGameData = function getGameData(matchIdArray) {
    return s3.headObjectAsync({
        Bucket: 'lolsearchgames',
        Key: '347341'
    }).then(function (results) {
        throw { code: 'Bucket data Found!' };
    }).catch(function (err) {
        if (err && err.code === "NotFound") {
            return; // this is OK
        }
        throw err;
    }).then(function () {
        return Promise.all(matchIdArray.map(function (matchId) {
            return lolapi.Match.getAsync(matchId);
        }));
    }).then(function (results) {  // see note below
        return results.filter(function (result) {
            return result;
        });
    });
};

请注意,在所有这些答案中,给出的原始代码都不会完全符合您的预期。 在您的原始代码中,如果gamedata为假,您只是忽略了“ Match.get” ... ...但是,您无法使用Promises做到这一点-最后一个.then在答案中会过滤掉getGameData返回的getGameData的空结果

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM