简体   繁体   中英

NodeJS, from promise chaining to async/await chaining

With NodeJS version 16.14.0 I'm trying to migrate from a promise.then().catch to a async/await management.
The problem is that with the first method, I was able to chain multiple functions sequentially, with the same big object passed through each of it (with return resolve(bigObject) and each function taking as input the same bigObject ). I was doing this because I'm able to manage micro-errors inside the data (so no catch involved), returning the user a full list of errors:

var commonData = {
    data1: ...
    data2: ...
    data3: ...
    data4: ...
    data5: ...
    data6: ...
};

return function1(commonData)
.then(function2)
.then(function3)
.then(function4)
.then(function5)
.then(function(result) {
    //Inside this .then, I'd have the "result" variable as result of the chain
})
.catch(error => { return reject(error); });

How can I do it with async await system? This is what I've tried so far:

var commonData = {
    data1: ...
    data2: ...
    data3: ...
    data4: ...
    data5: ...
    data6: ...
};

commonData = await function1(commonData);
commonData = await function2(commonData);
commonData = await function3(commonData);
commonData = await function4(commonData);
commonData = await function5(commonData);

//I was expecting to have inside "commonData" the same situation 
//as "result" in the chain above

Is there another way to chain functions with the same big object passed through that I'm missing?

EDIT:
2 of the functions I'm using in this part...they are designed this way because they are being called in other parts of the file too, I couldn't use them locally

//function 1
async function function1(commonData) {
    try {
        var data1 = await models.data1.findAll({where: {Domain_ID: [13,15]}})
        data1.forEach(function(dat) {
            commonData.data1.push(dat.dataValues);
        });
        
        return commonData;
    } catch (error) {
        throw error;
    }
}

//function2
async function function2(commonData) {
    try {
        var data2 = await models.data2.findAll();
        data2.forEach(function(dat) {
            commonData.data2.push(dat.dataValues);
        });
        
        return commonData;
    } catch (error) {
        throw error;
    }
}

No, there´s no other way. One of the reasons why Async/Await was implemented is that Promise chaining can look pretty ugly and messy. If you prefer .then() , just stick with it in this module.

For further reading: https://blog.logrocket.com/promise-chaining-is-dead-long-live-async-await-445897870abc/

The way you have it ( commonData = await function1(commonData) , etc.) is just fine. But if you don't want to do that, you could nest the calls:

const result = await function5(
    await function4(
        await function3(
            await function2(
                await function1(commonData)
            )
        )
    )
);

Or use a loop:

let result = commonData;
for (const fn of [function1, function2, function3, function4, function5]) {
    result = await fn(result);
}

Or you could keep using then . Although in general mixing async / await with explicit promise handlers via .then / .catch is confusing, there are some limited times where you might do it:

const result = await function1(commonData)
    .then(function2)
    .then(function3)
    .then(function4)
    .then(function5);

It works because async functions are just a way to consume and produce promises.


Or with the very big caveat that you know that the functions only modify the state of the object and don't return (fulfill their promise with) a different object, you could do:

await function1(commonData);
await function2(commonData);
await function3(commonData);
await function4(commonData);
const result = await function5(commonData);

but it's a big caveat.

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