1. Introduction
In the world of Javascript, asynchronous (asynchronous in JavaScript can block due to single threaded operation of JavaScript) is everywhere.
Express is a very popular web server framework in node environments, and a large proportion of Node Web applications use Express.
When writing server-side code using JavaScript, we inevitably use asynchronously. With the evolution of JavaScript and Node, our asynchronous processing methods have evolved accordingly.
Next, let’s take a look at the evolution of asynchronous processing in Express.
2. Asynchronous processing of JavaScript
In the asynchronous world, we need to find a way to obtain notifications of the completion of the asynchronous method. So what are the ways in JavaScript?
2.1. Callback
Callbacks are the most primitive and oldest asynchronous notification mechanism in JS.
function asyncFn(callback) { // Use setTimeout to simulate asynchronous setTimeout(function () { ('Execution is completed'); callback(); // Send a notice }, 2000); } asyncFn(function () { ('I will output after 2s'); });
2.2. Event monitoring
The function to get the result, listen for a certain time. After the asynchronous method is completed, the event is triggered to achieve the effect of notification.
2.3. Publish/Subscribe
Through observer mode, modify the publisher when asynchronously completes. At this time, the publisher will notify the subscriber of the change.
2.4、Promise
Promise is an improvement in the callback function. Using it, we can parallelize asynchronously and avoid callback hell.
function asyncFn() { return new Promise((resolve, reject) => { // Use setTimeout to simulate asynchronous setTimeout(function () { ('Execution is completed'); resolve(); // Send a notification (Do you feel the shadow of the callback?) }, 2000); }); } asyncFn() .then(function () { ('I will output after 2s'); });
2.5. Generator
The Generator function is an asynchronous programming solution provided by ES6.
The following code is just a simple demonstration. In fact, the use of Generator is relatively complicated. This is another topic and will not be discussed in this article.
function asyncFn() { return new Promise((resolve, reject) => { // Use setTimeout to simulate asynchronous setTimeout(function () { ('Execution is completed'); resolve(); // Send a notification (Do you feel the shadow of the callback?) }, 2000); }); } function* generatorSync() { var result = yield asyncFn(); } var g = generatorSync(); ().(()=>{ ('I will output after 2s'); });
2.6、async...await
It can be said that it is the best solution for handling asynchronous in current JavaScript.
function asyncFn() { return new Promise((resolve, reject) => { // Use setTimeout to simulate asynchronous setTimeout(function () { ('Execution is completed'); resolve(); // Send a notification (Do you feel the shadow of the callback?) }, 2000); }); } async function run(){ await asyncFn(); ('I will output after 2s'); } run();
3. Asynchronous processing in Express
In Express, we generally use solutions: callback function, promise, and async...await.
In order to build a demonstration environment, an express project is initialized through the express-generator. Generally, server-side projects are route calls business logic. So, we also follow this principle:
Open routers/ and we will see the following content. The following demo uses this file to demonstrate.
var express = require('express'); var router = (); /* GET home page. */ ('/', function(req, res, next) { ('index', { title: 'Express' }); }); = router;
3.1. Callback function handles Express asynchronous logic
In Express, routes can load multiple middleware, so we can write business logic according to the middleware writing method. In this way, the asynchronous logic can be split very easily through layers of next.
var express = require('express'); var router = (); function asyncFn(req, res, next) { setTimeout(() => { = {}; // Set the currently requested user next(); }, 2000); } function asyncFn2(req, res, next) { setTimeout(() => { = {}; // Set user permissions next(); }, 2000); } function asyncFn3(req, res, next) { setTimeout(() => { = { title: 'Express Async Test' }; // Set data ('index'); // Response }, 2000); } /* GET home page. */ ('/', asyncFn, asyncFn2, asyncFn3); // Execute middleware step by step = router;
3.2. Promise handles Express asynchronous logic
In this scheme, multiple business logic is wrapped as functions that return Promise. Combination calls are made through business methods to achieve one-in-one-out effect.
var express = require('express'); var router = (); function asyncFn(req, res) { return new Promise((resolve, reject) => { setTimeout(() => { = {}; // Set the currently requested user resolve(req); }, 2000); }); } function asyncFn2(req) { return new Promise((resolve, reject) => { setTimeout(() => { = {}; // Set user permissions resolve(); }, 2000); }); } function asyncFn3(res) { return new Promise((resolve, reject) => { setTimeout(() => { = { title: 'Express Async Test' }; // Set data ('index'); // Response }, 2000); }); } function doBizAsync(req, res, next) { asyncFn(req) .then(() => asyncFn2(req)) .then(() => asyncFn3(res)) .catch(next); // Unified exception handling}; /* GET home page. */ ('/', doBizAsync); = router;
3.3. async...await handles Express asynchronous logic
In fact, this solution also requires the support of Promise, but the writing method is more intuitive and the error handling is more direct.
It should be noted that Express is an early solution and does not handle global errors on async...await, so it can be used to handle it in a wrapper way.
var express = require('express'); var router = (); function asyncFn(req) { return new Promise((resolve, reject) => { setTimeout(() => { = {}; // Set the currently requested user resolve(req); }, 2000); }); } function asyncFn2(req) { return new Promise((resolve, reject) => { setTimeout(() => { = {}; // Set user permissions resolve(); }, 2000); }); } function asyncFn3(res) { return new Promise((resolve, reject) => { setTimeout(() => { }, 2000); }); } async function doBizAsync(req, res, next) { var result = await asyncFn(req); var result2 = await asyncFn2(req); = { title: 'Express Async Test' }; // Set data ('index'); // Response}; const tools = { asyncWrap(fn) { return (req, res, next) => { fn(req, res, next).catch(next); // Async... Error handling of await in Express } } }; /* GET home page. */ ('/', (doBizAsync)); // You need to wrap it with tools = router;
4. Summary
Although koa supports newer and better usage (koa is generator, koa2 native async). But as I have been following me since node, I still have a special affection for Express.
Some of the above solutions are no different from those used in koa. Combined with Express's huge ecosystem, it is like adding wings to the tiger.
This articleGithub address
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.