How to sync JavaScript callbacks?

前端 未结 6 1406
长发绾君心
长发绾君心 2020-12-01 08:54

I\'ve been developing in JavaScript for quite some time but net yet a cowboy developer, as one of the many things that always haunts me is synching JavaScript\'s callbacks.<

6条回答
  •  南笙
    南笙 (楼主)
    2020-12-01 09:08

    There are many, many ways to achieve this, I hope these suggestions help!

    First, I would transform the callback into a promise! Here is one way to do that:

    function aPromise(arg) {
        return new Promise((resolve, reject) => {
            aCallback(arg, (err, result) => {
                if(err) reject(err);
                else resolve(result);
            });
        })
    }
    

    Next, use reduce to process the elements of an array one by one!

    const arrayOfArg = ["one", "two", "three"];
    const promise = arrayOfArg.reduce(
        (promise, arg) => promise.then(() => aPromise(arg)), // after the previous promise, return the result of the aPromise function as the next promise
        Promise.resolve(null) // initial resolved promise
        );
    promise.then(() => {
        // carry on
    });
    

    If you want to process all elements of an array at the same time, use map an Promise.all!

    const arrayOfArg = ["one", "two", "three"];
    const promise = Promise.all(arrayOfArg.map(
        arg => aPromise(arg)
    ));
    promise.then(() => {
        // carry on
    });
    

    If you are able to use async / await then you could just simply do this:

    const arrayOfArg = ["one", "two", "three"];
    for(let arg of arrayOfArg) {
        await aPromise(arg); // wow
    }
    
    // carry on
    

    You might even use my very cool synchronize-async library like this:

    const arrayOfArg = ["one", "two", "three"];
    const context = {}; // can be any kind of object, this is the threadish context
    
    for(let arg of arrayOfArg) {
        synchronizeCall(aPromise, arg); // synchronize the calls in the given context
    }
    
    join(context).then(() => { // join will resolve when all calls in the context are finshed
        // carry on
    });
    

    And last but not least, use the fine async library if you really don't want to use promises.

    const arrayOfArg = ["one", "two", "three"];
    async.each(arrayOfArg, aCallback, err => {
        if(err) throw err; // handle the error!
        // carry on
    });
    

提交回复
热议问题