async is a process control toolkit that provides direct and powerful asynchronous functions. Designed for Node.js based on Javascript, it can also be used directly in the browser. This article mainly shares with you how to use the async function in Node.js. I hope it can help you.
With the new version of V8 engine, Node.js supports async function features starting from 7.6. On October 31 this year, Node.js 8 also became a new long-term support version, so you can use async functions in your code with confidence. In this article, I will briefly introduce what async functions are and how they can change the way we write Node.js applications.
1 What is async function
Using async function, you can write Promise-based asynchronous code just like synchronous code. Once you define a function using the async keyword, you can use the await keyword within the function. When an async function is called, it returns a Promise. When the async function returns a value, the Promise is fulfilled; if an error is thrown in the function, the Promise is rejected.
await keyword can be used to wait for a Promise to be resolved and return its realized value. If the value passed to await is not a Promise, it converts the value to a resolved Promise.
const rp = require('request-promise') async function main () { const result = await rp('https://google.com') const twenty = await 20 // 睡个1秒钟 await new Promise (resolve => { setTimeout(resolve, 1000) }) return result } main() .then(console.log) .catch(console.error)
2 Migrate to async function
If your Node.js application is already using Promise, then you only need to rewrite the original chain call To await these Promises of yours.
If your application is still using callback functions, you should gradually switch to using async functions. You can use this new technology when developing some new features. When you have to call some old code, you can simply wrap it into a Promise and call it in the new way.
To do this, you can use the built-in util.promisify method:
const util = require('util') const {readFile} = require('fs') const readFileAsync = util.promisify(readFile) async function main () { const result = await readFileAsync('.gitignore') return result } main() .then(console.log) .catch(console.error)
3 Best practices for Async functions
3.1 Using async functions in express
express originally supports Promise, so it is relatively simple to use async functions in express:
const express = require('express') const app = express() app.get('/', async (request, response) => { // 在这里等待 Promise // 如果你只是在等待一个单独的 Promise,你其实可以直接将将它作为返回值返回,不需要使用 await 去等待。 const result = await getContent() response.send(result) }) app.listen(process.env.PORT)
But As Keith Smith pointed out, there is a serious problem with the above example - if the Promise is ultimately rejected, since there is no error handling, the express route handler will hang.
To fix this problem, you should wrap your asynchronous handler in a function that handles errors:
const awaitHandlerFactory = (middleware) => { return async (req, res, next) => { try { await middleware(req, res, next) } catch (err) { next(err) } } } // 然后这样使用: app.get('/', awaitHandlerFactory(async (request, response) => { const result = await getContent() response.send(result) }))
3.2 Parallel Execution
For example, you are writing a program where an operation requires two inputs, one from the database and the other from an external service:
async function main () { const user = await Users.fetch(userId) const product = await Products.fetch(productId) await makePurchase(user, product) }
In this example, what will happen?
Your code will first get the user,
then get the product,
and finally make the payment.
As you can see, since there is no interdependence between the first two steps, you can actually execute them in parallel. Here, you should use the Promise.all method:
async function main () { const [user, product] = await Promise.all([ Users.fetch(userId), Products.fetch(productId) ]) await makePurchase(user, product) }
And sometimes, you only need the return value of the fastest resolved Promise - in this case, you can Use the Promise.race method.
3.3 Error handling
Consider the following example:
async function main () { await new Promise((resolve, reject) => { reject(new Error('error')) }) } main() .then(console.log)
When this code is executed, you will see something like this Message:
(node:69738) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: error
(node:69738) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
In newer Node.js versions, if a Promise is rejected and not handled , the entire Node.js process will be interrupted. Therefore you should use try-catch when necessary:
const util = require('util') async function main () { try { await new Promise((resolve, reject) => { reject(new Error('
The above is the detailed content of How to use async functions in Node.js. For more information, please follow other related articles on the PHP Chinese website!