如何捕获解决数组中所有promise的事件?

时间:2016-12-06 13:19:22

标签: javascript node.js promise bluebird

我正在使用Bluebird库和NodeJS(带有SailsJS框架)

Promise.all()数组中的所有承诺都已解决时,

promises未捕获该事件。

为了解决这个问题,应该做出哪些改变?

var Promise = require("bluebird");
var request = require('request');
var http = require('http');

function searchMultiple(titles) {

  var results = [];

  return new Promise( function( resolveGlobal, rejectGlobal ){

    var url = "http://xxx.xxx";
    var promises = [];

    titles.forEach(function (title, index) {

      promises[index] = new Promise( function (resolve, reject) {

        var data = {"x":title};

        request({
          uri: url,
          method: "POST",
          body : data
        }, function(error, response, body) {
             return resolve(body)
            }
          }
        },
        function (error, response, body) {
          console.log("error");
          return resolve();
        }
        );
      })
    })

    Promise.all(promises).then(function(combinedResults) {
      console.log("successfully resolved all promises");
      return resolveGlobal(combinedResults);
    }).catch(function (reason) {
      console.log("error");
      return rejectGlobal();
    });

  })
}

2 个答案:

答案 0 :(得分:1)

您不需要return resolve(value),因为只有resolve具有给定的结果值。

由于searchMultiple会返回一个承诺,因此您也无理由在Promise.all函数中创建新承诺。你应该回报你已经拥有的承诺!

因此resolveGlobal()是不必要的,您只需return结果,因为then会将其包装为已解析的值。

您的所有代码都可以重写为两个非常简单的函数

function searchMultiple(titles) {
  //Empty array of promises
  var promises = [];

  var url = "http://xxx.xxx";

  //Get a promise for each title and push to array
  titles.forEach(function(title){
    promises.push(getData(title, url));
  });

  //Wait for all promises to resolve, and return the result
  return Promise.all(promises)
    .then(function(arrayOfResults){
      //If this only shall return the array, this can be omitted aswell as the catch!
      return arrayOfresults;
    })
    .catch(function(reason){
      //Handle errors
    });
}

function getData(title, url){
  return new Promise(function(resolve, reject){
    var data = {"x":title};
        request({
          uri: url,
          method: "POST",
          body : data
        }, function(error, response, body) {
             resolve(body)
            }
          }
        },
        function (error, response, body) {
          console.log("error");
          //Consider rejecting here instead since you'll get a result that is 'undefined'
          resolve();
        });
  });
}

您应该考虑拒绝错误处理程序中的promise,而不是使用未定义的值解析它。如果你得到一个值为undefined的结果数组,那么你最终可能会遇到错误。

答案 1 :(得分:0)

试试这个:

var Promise = require('bluebird');
var request = require('request');

function searchMultiple(titles) {
  return new Promise(function (resolveGlobal, rejectGlobal) {
    var url = 'http://xxx.xxx';
    var promises = [];

    titles.forEach(function (title) {
      promises
        .push(new Promise(function (resolve, reject) {
          var data = {
            'x': title
          };

          request({
              uri: url,
              method: 'POST',
              body: data
            },
            function (error, response, body) {
              if (!error && response.statusCode == 200) {
                return resolve(body);
              }

              return reject(error);
            });
        }));
    });

    Promise
      .all(promises)
      .then(function (combinedResults) {
        console.log('successfully resolved all promises');

        return resolveGlobal(combinedResults);
      })
      .catch(function (error) {
        console.log('error');

        return rejectGlobal(error);
      });
  });
}

并致电功能:

searchMultiple([...])
  .then(function (results) {
    console.log(results);
  })
  .catch(function (error) {
    console.log(error);
  });