Running asynchronous functions sequentially with promises

I am trying to run several asynchronous tasks sequentially using promises. Each task should start immediately after the previous one. This is a simplified example of what I tried:

var order = [];
var tasks = [
    new Promise(resolve => {
        order.push(1);
        setTimeout(() => {
            order.push(2)
            resolve();
        }, 100);
    }),
    new Promise(resolve => {
        order.push(3);
        setTimeout(() => {
            order.push(4)
            resolve();
        }, 100);
    }),
    new Promise(resolve => {
        order.push(5);
        resolve();
    })
];

tasks.reduce((cur, next) => cur.then(next), Promise.resolve()).then(() => {
    console.log(order); // [ 1, 3, 5 ]
});
setTimeout(() => console.log(order), 200); // [ 1, 3, 5, 2, 4 ]

I expect it to orderbe equal [ 1, 2, 3, 4, 5 ]in the callback function. However, I got these strange results ( [ 1, 3, 5 ]in a thencallback and [ 1, 3, 5, 2, 4 ]in a delayed function). What am I missing?

+4
source share
4 answers

When you write something like

new Promise(resolve => {
    order.push(1);
    setTimeout(() => {
        order.push(2)
        resolve();
    }, 100);
});

, , 0,1 .
, , , promises .

, , , , , !

, - , , , , , -

var tasks = [
    _ => new Promise(resolve => {
            order.push(1);
            setTimeout(() => {
                order.push(2)
                resolve();
            }, 100);
    }),
    _ => new Promise(resolve => {
            order.push(3);
            setTimeout(() => {
                order.push(4)
                resolve();
            }, 100);
    }),
    _ => new Promise(resolve => {
            order.push(5);
            resolve();
    }),
];

( ES2015 )

, , .

, , , ..

(function iterate(i) {
    tasks[i]().then(() => {          // when done
        if (tasks[++i]) iterate(i);  // call the next one
    });
})(0);

FIDDLE


Edit:

Array.reduce, , , , promises

tasks.reduce((cur, next) => cur.then(next), Promise.resolve()).then(() => {
    // all done, chain is complete !
});
+5

, setTimeout ( 2, 4 log order) , .. "". ( Promise reduce) , .

var order = [];
var tasks = [
    new Promise(resolve => {
        order.push(1); // 1. callback executes immediately pushing 1 into order
        setTimeout(() => { // 2. setTimeout executes, pushing the callback into the event queue after 100ms
            order.push(2) // 8. callback executes, pushing 2 into order
            resolve();
        }, 100);
    }),
    new Promise(resolve => {
        order.push(3); // 3. callback executes immediately pushing 3 into order
        setTimeout(() => { // 4. setTimeout executes, pushing the callback into the event queue after 100ms
            order.push(4) // 9. callback executes, pushing 4 into order
            resolve();
        }, 100);
    }),
    new Promise(resolve => {
        order.push(5); // 5. callback executes immediately pushing 5 into order 
        resolve();
    })
];

console.log(order); // [ 1, 3, 5 ]    

// 6. reduce executes immediately, executes Promise.resolve which logs order and then loops through order and executes the callback everytime
tasks.reduce((cur, next) => cur.then(next), Promise.resolve()).then(() => {
    console.log(order); // [ 1, 3, 5 ]
});

setTimeout(() => {
    console.log(order); // 10. callback executes and logs order
}, 200); // 7. setTimeout executes, pushing the callback into the event queue after 200ms

1 7, , ( setTimeout), , , , , ( 8, 9 10).

, , .

0

-, , , :

"use strict";
var order = [];
var i = 0;
function next(){
    if(tasks[++i]) tasks[i]()
}
var tasks = [
    function() {
        order.push(1);
        setTimeout(() => {
            order.push(2)
            next()
        }, 100);
    },
    function() {
        order.push(3);
        setTimeout(() => {
            order.push(4)
            next();
        }, 100);
   },
   function() {
        order.push(5);
        next()
        console.log(order)
    }
];

tasks[0]()
0

Each asynchronous function has a synchronous part, an installation leading to a (synchronous) return of the promise.

0
source

All Articles