简体   繁体   中英

Promise.all([..]).then never resolves

I have a number of individual Promises that look like this:

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

They all use this method called getFromApi() to perform a request:

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;
});

Because I need to run the requests together and get an array including all results, I added all individual Promises into a 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);
  })
};

The problem is, although the requests are performed fine as I can see from the logs on getFromApi() method, the array of results is never returned. The method runs but apparently never gets to the function inside .then and this:

console.log('Then: ', results);

is never reached (neither the catch function under it).

Seems as if the program runs only until all requests are performed and forgets to return results.

You're never resolving the promise.

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

Your getFromApi function also has a callback but it never gets run. You probably want callback(body); instead of return body;

function getFromApi(path, callback) accepts a callback argument so lets use that as the callback for request instead of the anonymous function you have

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

Now lets use that anonymous function, slightly modified to call resolve/reject as required, in performancePerMonth etc

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);
        }
    });
});

You may want to check response.statusCode is one that indicates a successful request before blindly resolving the body too - many request API's don't consider a non 2xx status returned in the response as an error

so, you may need something like

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);
            }
        }
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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