Understanding the usage of async & await in Koa2 and Koa2async

Source: Internet
Author: User
Tags node server

Understanding the usage of async & await in Koa2 and Koa2async

Koa is a well-known Node Server framework, with versions 1.x and 2.x. The former uses generator for asynchronous operations, and the latter uses the latest async/await solution.

When I started using this method, I encountered a problem. The Code is as follows:

Const Koa = require ('koa'); const app = new koa (); const doSomething = time => {return new Promise (resolve => {setTimeout (() =>{ resolve ('Task done! ')}, Time)} // print the request information app. use (ctx, next) => {console. log ('$ {ctx. method }::: {ctx. url} ') next ()}) app. use (async ctx => {const result = await doSomething (3000) console. log (result); ctx. body = result}) app. listen (0, 3000 );

Let's test: curl http: // localhost: 3000

Expected results:

(3 seconds later...) task done!

However, the reality is:

(Now)
Not Found

What? Why is it not executed as expected? This requires us to understand how the middleware in Koa is connected in series. Refer to the source code to concatenate middlewares as follows:

Function compose (middleware) {return function (context, next) {// This index is used to count, prevent next from being called multiple times. let index =-1 // return dispatch (0) function dispatch (I) {// If next is called multiple times, if (I <= index) return Promise. reject (new Error ('Next () called multiple times ')) index = I // retrieve the first middleware let fn = middleware [I] // execute if (I = middleware. length) fn = next if (! Fn) return Promise. resolve () try {/** is the key here. What does Promise. resolve mean? The Promise. resolve Method has three forms: Promise. resolve (value); Promise. resolve (promise); Promise. resolve (theanable); all three forms generate a new Promise. The first form provides the ability to customize the value of Promise, which corresponds to Promise. reject (reason. The difference between the two is that the Promise state is different. The second form provides the ability to create a copy of Promise. The third form is to convert a Promise-like object into a real Promise object. One of its important functions is to encapsulate a Promise object of other implementations into a Promise object of the current implementation. For example, if you are using bluebird, but now you have a Promise of Q, you can use this method to convert Q Promise into a Promise of bluebird. The second form can be included in the third form **/return Promise. resolve (fn (context, function next () {// execute the next middleware, and the returned result is also a Promise return dispatch (I + 1)} catch (err) {return Promise. reject (err )}}}}

With the above foundation, let's take a look at the previous problem. Why didn't response Return immediately after the second middleware was executed?

Because the first middleware is not an asynchronous function.

Since every next method execution actually returns a Promise object, if we execute an asynchronous operation in a middleware, we need to add await before executing this middleware.

Let's rewrite the previous code.

app.use(async (ctx, next) => {  console.log(`${ctx.method}:::${ctx.url}`)  await next()})app.use(async ctx => {  const result = await doSomething(3000)  console.log(result);  ctx.body = result})

Okay, no problem. If you want to execute clap:

Error Handling

With the powerful Promise capabilities and the async/await syntax, we only need to write the try/catch operation in the middleware on the outermost layer to capture all the later middleware exceptions!

app.use(async (ctx, next) => {  try{    await next()  }catch(err){    console.log(err)  }})app.use(async (ctx)=>{  throw new Error('something wrong!')  ctx.body = 'Hello'})

Full Control Based on the middleware chain and Promise-based facts make everything easy to operate. If (err) return next (err) is no longer everywhere, but only promise

The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.