最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

node.js - Javascript : promise chain vs. asyncawait? - Stack Overflow

programmeradmin2浏览0评论

I am learning about Javascript Promise and async/await. The sample code below asynchronously reads and parses a JSON file in node.js (my node.js version is v10.0.0).

In the sample code, ChainReadJson function and AwaitReadJson function are doing the same thing, reading and parsing a JSON file. The difference is that ChainReadJson function uses a promise chain, while AwaitReadJson function uses async/await.

const FS = require("fs");

function ReadFile(fileName) {
    return new Promise((Resolve, Reject) => {
        FS.readFile(fileName, 'utf8', (error, result) => {
            if (error)
                Reject(error);
            else
                Resolve(result);
        });
    });
}

// function using promise chain

function ChainReadJson(fileName, CallBack) {
    ReadFile(fileName)
        .then(
            res => JSON.parse(res),
            err => {
                Message(-1, err.message);
            }
        )
        .then(
            res => {
                if (res !== undefined)
                    CallBack(fileName, res);
            },
            err => {
                Message(-2, err.message);
            }
        );
}

// function using async/await

async function AwaitReadJson(fileName, CallBack) {
    let res, json;

    try {
        res = await ReadFile(fileName);
    }
    catch (err) {
        Message(-1, err.message);
        return;
    }
    try {
        json = JSON.parse(res);
    }
    catch (err) {
        Message(-2, err.message);
        return;
    }
    CallBack(fileName, json);
}

ChainReadJson('test.json', PrintJSON);
AwaitReadJson('test.json', PrintJSON);

// common functions

function PrintJSON(fileName, json) {
    console.log(`JSON[${fileName}]:`, json);
}

function Message(n, str) {
    console.log(`[${n}]`, str);
}

When writing the code for ChainReadJson function using promise chain, I had difficulties controlling execution results and errors. However, when writing the code for AwaitReadJson function using async/await, those difficulties are mostly disappeared.

Do I correctly understand the benefits of async/await? What are the disadvantages of async/await compared to promise chain?

(The sample code is a modified version of the code in this answer. The original code uses promise chain only, and is written to know exactly where in the chain the error occurred and what is the error)

I am learning about Javascript Promise and async/await. The sample code below asynchronously reads and parses a JSON file in node.js (my node.js version is v10.0.0).

In the sample code, ChainReadJson function and AwaitReadJson function are doing the same thing, reading and parsing a JSON file. The difference is that ChainReadJson function uses a promise chain, while AwaitReadJson function uses async/await.

const FS = require("fs");

function ReadFile(fileName) {
    return new Promise((Resolve, Reject) => {
        FS.readFile(fileName, 'utf8', (error, result) => {
            if (error)
                Reject(error);
            else
                Resolve(result);
        });
    });
}

// function using promise chain

function ChainReadJson(fileName, CallBack) {
    ReadFile(fileName)
        .then(
            res => JSON.parse(res),
            err => {
                Message(-1, err.message);
            }
        )
        .then(
            res => {
                if (res !== undefined)
                    CallBack(fileName, res);
            },
            err => {
                Message(-2, err.message);
            }
        );
}

// function using async/await

async function AwaitReadJson(fileName, CallBack) {
    let res, json;

    try {
        res = await ReadFile(fileName);
    }
    catch (err) {
        Message(-1, err.message);
        return;
    }
    try {
        json = JSON.parse(res);
    }
    catch (err) {
        Message(-2, err.message);
        return;
    }
    CallBack(fileName, json);
}

ChainReadJson('test.json', PrintJSON);
AwaitReadJson('test.json', PrintJSON);

// common functions

function PrintJSON(fileName, json) {
    console.log(`JSON[${fileName}]:`, json);
}

function Message(n, str) {
    console.log(`[${n}]`, str);
}

When writing the code for ChainReadJson function using promise chain, I had difficulties controlling execution results and errors. However, when writing the code for AwaitReadJson function using async/await, those difficulties are mostly disappeared.

Do I correctly understand the benefits of async/await? What are the disadvantages of async/await compared to promise chain?

(The sample code is a modified version of the code in this answer. The original code uses promise chain only, and is written to know exactly where in the chain the error occurred and what is the error)

Share Improve this question edited Feb 21, 2020 at 22:12 pdh0710 asked May 7, 2018 at 22:21 pdh0710pdh0710 4271 gold badge5 silver badges14 bronze badges 6
  • 1 Uou understand both promise chains and async/await well . . . and the rest is opinion which this site isn't good at. Ignoring that in my humble opinion there aren't really any disadvantages to async/await aside from it not being supported everywhere. – generalhenry Commented May 7, 2018 at 22:29
  • What errors did you get with using promise chain? And how did you use ChainedPromiseJSON? The 2 codes are not the same, in the promise chain you only execute Callback if the return from JSON.parse was not undefined, whereas in your await case, you execute Callback always. – cowbert Commented May 7, 2018 at 22:35
  • @generalhenry : Thank you for opinion. – pdh0710 Commented May 7, 2018 at 22:39
  • @cowbert : The sample code is correctly working. If you read this answer, you can understand the sample code more easily. – pdh0710 Commented May 7, 2018 at 22:41
  • why did you create 2 separate questions. Anyway, if the previous step (the first then caused an error, then it will hit the error callback in the second then). Checking for res !== undefined will only get executed if JSON.parse returns undefined, which won't ever happen, it will throw a SyntaxError instead. – cowbert Commented May 7, 2018 at 22:48
 |  Show 1 more comment

2 Answers 2

Reset to default 13

Indeed, async/await were designed to reduce boilerplate and make asynchronous programs easier to write, compared to callbacks, promises, and generator functions.

  • While promises were created with the same goal, they had the additional constraint of having to work in the existing JS engines -- so their syntax is more complicated. Using async/await requires a relatively new JS engine. It might not matter if you're writing a node.js app of your own, but a library might need to be compatible with older node.js versions (and I'm not sure if you can transpile it for use in older browsers without generator support).
  • Since async/await is newer, it's not as optimized. A comparison made in the last year reports Bluebird promises (a JS library implementing simplified version of promises) outperforming async/await in a certain benchmark. (Of course this may not matter when your use-case is making a few network requests.)
  • You might still need promises to execute several asynchronous actions in parallel (edit: if you need their results)

While async/await can be a nice way to cleanup asynchronous logic, it's worth pointing out that the promise logic can be cleaned up significantly, to the point of being very similar to the async/await alternative:

const fs = require("fs");
const util = require("util")

//Could also use the experimental "fs/promise" api from node v10
const promisifiedReadFile = util.promisify(fs.readFile);

const readFile = (fileName) => promisifiedReadFile(fileName, 'utf8');

function chainReadJson(fileName, callback) {
    return readFile(fileName)
        .then(json => JSON.parse(json))
        .then(result => callback(null, result))
        .catch(e => {
            console.log("Error reading or parsing file", e.message);
            callback(e)
        });
}

The only functional difference here is that all the error logging occurs at one place, at the end of the chain.

It's possible to preserve the split logging for the readFile and the JSON.parse, but that is admittedly a bit trickier. You generally want to re-throw errors after handling them, so that the downstream .then handlers are skipped: but if you throw the error again, it'll be caught again by the downstream .catch handlers, which will cause duplicate logging, if you don't find a way to filter it out.

It's doable, but it's a bit of a pain, so I left it out of the above code.

发布评论

评论列表(0)

  1. 暂无评论