Wait for each promise to be done after continuing

2019-08-12 11:13发布

问题:

Below I have two functions. One of the returns a promise and I want in each and every loop to wait for it to finish first and then move one. As you'll see below the result is not the desired/synchronous. Should I not use async.forEachof

function test(num, callback)
{
    console.log("inside function: "+num)
    return new Promise((resolve, reject) => {
        my.promise(num).then(() => {
            console.log("done: "+num)
            resolve(callback);
        }).catch(e => console.error(e));
    }).catch(console.error);
}

function start_function()
{
    //stuff
    async.forEachOf(arr, function (itm, i, callback){
        console.log(i)
        test(i, callback).catch(e => console.error(e));
    }, function (err) {
        console.log("ALL DONE")
    });
}

Result:

0
inside function 0
1
inside function 1
2
inside function 2
done: 0
done: 2 //wrong should always be 1, finished before the previous promise.
done: 1 //wrong
ALL DONE

I do not want to use PromiseAll not because I dont want but because I need each promise to wait for the previous one's result, and then start the next one. It is pointless therefore to gather them all and then wait for them to be done in whatever order and to what I need to do.

回答1:

If I'm not wrong what exactly you are trying to do, but you should avoid passing callback in Promise function and resolving it. You can achieve the same with this code and remove callback from test function as well.

function start_function()
{
    //stuff
    arr.forEach(async function (itm, i, array){
        console.log(i)
        try {
            await test(i);
        }
        catch(err){
            console.log(err);
        }
    });
}

Here's how test function may look like,

function test(num)
{
    console.log("inside function: "+num)
    return new Promise((resolve, reject) => {
        my.promise(num).then(() => {
            console.log("done: "+num)
            resolve();
        }).catch(e => {
              console.error(e)
              reject(e);
        });
    });
}


回答2:

What about this approach:

(function loopOnItems(i) {           

        dummyGoogleAPI.someAsyncMethod(data).then(function (_response) {                
            // do something with response          
        })
        .catch(function (error) {
            console.error(error);
        });

        if (--i){
            loopOnItems(i);    
        }//  decrement i and call loopOnItems again if i > 0
        else{
            _callback(errors);
        }            
})(count);

You have some count and we call loopOnItems method till count > 0