Promise.all([..])。然后永远不会解决

时间:2016-12-21 17:52:57

标签: javascript node.js promise

我有许多个人承诺,如下所示:

var performancePerMonth = new Promise(function(resolve, reject) {
  var path = some_path;
  getFromApi(path);
});

他们都使用名为getFromApi()的方法来执行请求:

function getFromApi(path, callback) {

  request({
    method: 'GET',
    url: base_uri + path,
    headers: { 'TOKEN': 'MY_ACCESS_TOKEN' }
  },

  function (error, response, body) {
    console.log('Status:', response.statusCode);
    console.log('Headers:', JSON.stringify(response.headers));
    console.log('Response:', body);
    return body;
});

因为我需要一起运行请求并获得包含所有结果的数组,所以我将所有单独的Promise添加到Promise.all中:

exports.perform = function(req, response) {
  Promise.all([performancePerMonth, performancePerPlayer,..]).then(function(results) {
    console.log('Then: ', results);
  }).catch(function(err) {
    console.log('ERROR Promise.all');
    console.log('Catch: ', err);
  })
};

问题是,虽然从getFromApi()方法的日志中可以看到请求执行得很好,但是从不返回结果数组。该方法运行但显然从未到达.then内的函数,并且:

console.log('Then: ', results);
永远不会达到

(它下面的捕获函数都没有)。

好像程序只在所有请求都执行之前运行并忘记返回结果。

2 个答案:

答案 0 :(得分:1)

你永远不会解决这个承诺。

var performancePerMonth = new Promise(function(resolve, reject) {
  var path = some_path;
  getFromApi(path, resolve);
});

您的getFromApi函数也有回调但它永远不会运行。您可能需要callback(body);而不是return body;

答案 1 :(得分:0)

function getFromApi(path, callback)接受回调参数,因此我们将其用作request的回调而不是您拥有的匿名函数

function getFromApi(path, callback) {
  request({
    method: 'GET',
    url: base_uri + path,
    headers: { 'TOKEN': 'MY_ACCESS_TOKEN' }
  }, callback);
}

现在让我们使用匿名函数,稍加修改以根据需要调用resolve {reject} performancePerMonth

var performancePerMonth = new Promise(function(resolve, reject) {
    var path = some_path;
    getFromApi(path, function (error, response, body) {
        if (error) {
            reject(error);
        } else {
            console.log('Status:', response.statusCode);
            console.log('Headers:', JSON.stringify(response.headers));
            console.log('Response:', body);
            resolve(body);
        }
    });
});

您可能希望在盲目解析正文之前检查response.statusCode是否表示请求成功的请求 - 许多请求API不会将响应中返回的非2xx状态视为错误

所以,你可能需要像

这样的东西
var performancePerMonth = new Promise(function(resolve, reject) {
    var path = some_path;
    getFromApi(path, function (error, response, body) {
        if (error) {
            reject(error);
        } else {
            console.log('Status:', response.statusCode);
            console.log('Headers:', JSON.stringify(response.headers));
            console.log('Response:', body);
            if (response.statusCode >= 200 && response.statusCode < 300) {
                resolve(body);
            } else {
                reject(response.statusCode);
            }
        }
    });
});