Skip to content Skip to sidebar Skip to footer

Async Functions Vs Await

I'm coming from a PHP background and I'm trying to learn NodeJS. I know that everything in Node is async but I've found that i've been using the async / await combo quite a lot in

Solution 1:

But I'm worried that I might be missing something fundamental here.

Nope, you're not, that's exactly what you want to do, assuming this.doSomething(data) is asynchronous (and if it's an ajax call, one hopes it is async) and that it returns a promise (which all functions defined with the async keyword do implicitly). (If it's not asynchronous, you don't need the await, although it's allowed.)

You're probably being a bit confused (understandably) by the fact that things are going through a transition. Until recently, the overwhelming convention in Node APIs (the built-in ones and ones provided by third-party modules) was to use the "Node callback" pattern, which is that a function that will do asynchronous work expects its last argument to be a callback, which it will call with a first argument indicating success/failure (null = success, anything else is an error object) with subsequent arguments providing the result. (Your second example assumes doSomething is one of these, instead of being a function that returns a promise.)

Example: fs.readFile, which you use like this:

fs.readFile("/some/file", "utf-8", function(err, data) {
    if (err) {
        // ...handle the fact an error occurred..return;
    }
    // ...use the data...
});

This style quickly leads to callback hell, though, which is one of the reasons promises (aka "futures") were invented.

But a lot of Node APIs still use the old pattern.

If you need to use "Node callback"-pattern functions, you can use util.promisify to create promise-enabled versions of them. For instance, say you need to use fs.readFile, which uses the Node callback pattern. You can get a promise version like this:

const readFilePromise = util.promisify(fs.readFile);

...and then use it with async/await syntax (or use the promise directly via then):

const data = await readFilePromise("/some/file", "utf-8");

There's also an npm module called promisify that can provide a promise-ified version of an entire API. (There's probably more than one.)

Just because promises and async/await replace the old Node callback style in most cases doesn't mean callbacks don't still have a place: A Promise can only be settled once. They're for one-off things. So callbacks still have a place, such as with the on method of EventEmitters, like a readable stream:

fs.createReadStream("/some/file", "utf-8")
    .on("data", chunk => {
        // ...do something with the chunk of data...
    })
    .on("end", () => {
        // ...do something with the fact the end of the stream was reached...
    });

Since data will fire multiple times, it makes sense to use a callback for it; a promise wouldn't apply.

Also note that you can only use await in an async function. Consequently, you may find yourself getting into the habit of a "main" module structure that looks something like this:

// ...Setup (`require` calls, `import` once it's supported, etc.)...
(async () => {
    // Code that can use `await `here...
})().catch(err => {
    // Handle the fact an error/promise rejection occurred in the top level of your code
});

You can leave the catch off if you want your script to terminate on an unhandled error/rejection. (Node doesn't do that yet, but it will once unhandled rejection detection matures.)

Alternately, if you want to use a promise-enabled function in a non-async function, just use then and catch:

this.doSomething()
    .then(result => {
        // Use result
    })
    .catch(err => {
        // Handle error
    });

Note: async/await is directly supported in Node 7.x and above. Be sure your target production environment supports Node 7.x or above if your'e going to use async/await. If not, you could transpile your code using something like Babel and then use the transpiled result on the older version of Node.

Post a Comment for "Async Functions Vs Await"