简体   繁体   中英

call async function for each array element of a promise result object, make changes and return this object

A Bluebird Promise returns an object that contains two arrays of objects, cars and contracts. Then, I want to iterate over the cars, call an asynchronous function and, based on the returned value, make some changes to the second array and return the initial result object with these changes. I can't figure out how to do this with promises. Or with async, for that matter. I feel like they should be nested promises, but i can;t get it to work at all.

the version with promises:

somePromise().then(function (result) {

    Promise.each(result.cars, function (car) {
        makeAsyncCall(car.id, function (err, resultArray) {
            if (err) {
                throw new Error();
            }

            result.contracts.forEach(function (contract) {
                if (resultArray.indexOf(contract.id) > -1) {
                    contract.car = car.id;
                }
            });
        });

    }).then(function (eachResult) {
        //eachResult is result.firstArray, which is not interesting.
        return result;
    });

}).then(function (result)) {
    //this gets called before my promise.each gets executed??
}

Can anyone give me a hint as to where my mistake is?

Have a look at my rules of thumb for promise development. The two specific points that apply to your code are:

  • promisify your async callback-taking functions before using them, specifically

     var makeCall = Promise.promisify(makeAsyncCall); 
  • always return promises from your functions that do asynchronous things. This is especially true for callbacks, like the function() { Promise.each(…).then(…) } and the function() { makeAsyncCall(…) } .

With those, you should get to the following:

somePromise().then(function(result) {
    return Promise.each(result.cars, function(car) {
        return makeCall(car.id).then(function(resultArray) {
            // a lookup structure of contracts by id could make this more efficient
            result.contracts.forEach(function (contract) {
                if (resultArray.indexOf(contract.id) > -1)
                    contract.car = car.id;
            });
        });
    }).return(result);
}).…

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