随着Node.js v7.6.0版本开始支持async/await,在服务器端进行Node.js编程也终于有了最佳的异步解决方案。
只要你Node.js安装的是v7.6.x以上版本,都是支持async/await语法的。
所以只要你安装的是Node.js新版本,在Express程序里面是可以直接使用async/await方法的。
参考下面实例:
const express = require('express');
const app = express();
const fs = require('fs');
function readFileAsync(filepath) {
return new Promise(function (resolve, reject) {
fs.readFile(filepath, function (err, data) {
if (err) {
reject(err);
return;
}
resolve(JSON.parse(data.toString()));
});
});
}
app.get('/', async (req, res, next) => {
const data = await readFileAsync('./test.json');
res.send(data.worlds);
});
// Error Handler
app.use(function (err, req, res, next) {
console.error('Error:', err);
res.status(500).send(err.message);
});
const server = app.listen(3000, () => {
let port = server.address().port;
console.log(`server is running on port ${port}`);
});
代码可以正常执行,通过实例发现不对express进行任何改造async/await也能使用,现在我们读取一个不存在的文件看看存在的问题。
const data = await readFileAsync('./test2.json');
此时会发生请求不能及时响应,过一段时间出现UnhandledPromiseRejectionWarning的错误提示,这是因为async函数里面的错误默认不能被错误中间件捕获的原因。
怎么才能捕获async函数里面的错误呢?
解决方法:
1,添加try/catch
app.get('/', async (req, res, next) => {
try{
const data = await readFileAsync('./test2.json');
res.send(data.worlds);
}catch(err){
next(err);
}
});
运行发现此时错误可以被错误中间件捕获处理了,如果在所有可能出现错误的地方的都添加try/catch,代码看起来就太不优雅精简了,更好一点的方式就是写一个方法可以自动捕获async函数里面的错误。
2,使用Promise对象
因为async函数默认返回的是一个Promise对象,所以可以用下面的asyncHandler函数捕获async函数中出现的异常错误。
//执行捕获异常错误
const asyncHandler = function (fn) {
return function (...args) {
Promise.resolve(fn(...args)).catch(args[2]);
}
}
app.get('/', asyncHandler(async (req, res, next) => {
const data = await readFileAsync('./test2.json');
res.send(data.worlds);
}));
不过这些实现代码看起来还是怪怪的,每个用到的地方都要添加asyncHandler函数,这是作为一个有追求的程序员不能忍受的,我们要追求更极致的方式。
3,更精简的实现方式是我们可以通过修改express的底层router来实现:
const Layer = require('express/lib/router/layer');
Object.defineProperty(Layer.prototype, 'handle', {
enumerable: true,
get() {
return this.__handle;
},
set(fn) {
if (fn.length === 4) {
this.__handle = fn;
} else {
this.__handle = (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next);
}
},
});
这样修改之后就可以全局捕获express路由async函数中出现的异常错误了,下面是完整的代码:
const express = require('express');
const app = express();
const fs = require('fs');
function readFileAsync(filepath) {
return new Promise(function (resolve, reject) {
fs.readFile(filepath, function (err, data) {
if (err) {
reject(err);
return;
}
resolve(JSON.parse(data.toString()));
});
});
}
const Layer = require('express/lib/router/layer');
Object.defineProperty(Layer.prototype, 'handle', {
enumerable: true,
get() {
return this.__handle;
},
set(fn) {
if (fn.length === 4) {
this.__handle = fn;
} else {
this.__handle = (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next);
}
},
});
app.get('/', async (req, res, next) => {
const data = await readFileAsync('./test2.json');
res.send(data.worlds);
});
// Error Handler
app.use(function (err, req, res, next) {
console.error('Error:', err);
res.status(500).send(err.message);
});
const server = app.listen(3000, () => {
let port = server.address().port;
console.log(`server is running on port ${port}`);
});
so easy...^_^
分享到:
相关推荐
首先,我们回顾一下直接在Express中使用async/await的情况。以下是一个简单的示例,其中使用`promisify`将原始的异步fs.readFile方法转换为返回Promise的版本,以便与async/await配合使用: ```javascript const ...
但是在有了es7的async/await,基本不再需要回调了,所以本篇是基于async/await对mysql进行一次操作封装,让查询更加方便。(node版本需>=7.0)。 原理 简单来说,async/await的实现原理是基于promise,根据promise...
在Express中,`async/await`可以与中间件函数结合使用,以更直观的方式处理请求和响应。传统的Express中间件函数通常接收`req`(请求)、`res`(响应)和`next`(传递控制权给下一个中间件)作为参数。当这些中间件...
在Express中,可以轻松地在路由处理函数中使用: ```javascript async function run() { await asyncFn(); console.log('我会在2s后输出'); } run(); ``` 这种方式极大地提高了代码的可读性和可维护性。 在...
我们在编写express后台,经常要有许多异步IO的处理。在远古时代,我们都是用chunk函数处理,也就是我们最熟悉的那种默认第一个参数是error的函数。我们来模拟一个Mongo数据库的操作,感受一下。 mongoDb.open...
A koa2 starter by using mysql, gulp includes async/await, pm2, express-style middlewares. koa2 starter,使用mysql和gulp,并且包含async/await特性、pm2部署和express风格的中间件
此npm模块允许您在打字稿源中使用此解决方案。 安装 # With npm npm install --save async-wrapper-express-ts # With yarn yarn add async-wrapper-express-ts 用法 import asyncWrapper from 'asyncWrapper' .....
3. **异常处理**:由于网络请求可能出现错误,我们需要在`async`函数中使用`try...catch`语句捕获可能的异常,确保程序的健壮性。 4. **渲染结果**:解析到的猫gif数据可以包含URL,将其插入到HTML元素中,实现动态...
- **服务器端应用**:Node.js 中的 Express 框架支持使用 async/await 来处理 HTTP 请求,可以更加简洁地编写路由处理函数,提高服务器端的处理效率。 #### 结论 Async JavaScript 作为现代 Web 开发中不可或缺的...
@ awaitjs / express 使用async / await编写Express中间件和路由处理程序用法const { addAsync } = require ( '@awaitjs/express' ) ;// Or, if you want to use `wrap()`const { wrap } = require ( '@awaitjs/...
通常,你可以直接在Node.js环境中使用它们。不过,如果你想要使用一些辅助工具或者库来更好地处理异步操作,例如`util.promisify`来转换回调函数为返回Promise的方法,那可能需要安装`util`或者其他相关的库。 现在...
当然,我很乐意为您提供详细的代码说明。以下是对您提供的使用 Express 和 Vue3 搭建的 ChatGPT 演示网页代码的 500 字说明: ...由于 ChatGPT API 有一定的延迟,服务器使用了 async/await 语法来等待 API 的响应。
表达异步错误此仓库与我的博客文章有关使用async / await进行Express错误处理的文章一起显示。 相关代码在src/app.js 。 此存储库还包含涉及Babel,ESLint,Prettier等的设置-
在Express / Koa应用程序中使用Koa / Express中间件。 它可以将中间件转换为Express和koa中间件之间的另一种形式。 需求 Koa-to-express需要koa@2.0.0和express@4.0.0或更高。 如果要使用ES2015的async / await...
在Express中使用`async`函数可以简化路由处理,但是需要注意错误处理。不正确地使用`async`函数可能会导致未捕获的异常,从而中断应用。为了避免这个问题,可以创建一个中间件函数来处理可能出现的错误: ```...
理解数据库的连接、查询和事务处理,以及如何在Node.js中使用ORM(对象关系映射)库,如Sequelize或Mongoose,是提高异步编程能力的重要一环。 8. **HTTP服务器**:Node.js内置的http模块使得创建高性能的Web服务器...
在express中时使用 Async/await 编写异步代码时,每个 async 函数都要包裹在try/catch中,代码量多了看着冗余不优雅,express又不像koa的异步机制可以订阅全局的error事件,为了解决这个问题,需要写个捕获异步函数...
因为最新的node从v7.6.0开始已经支持async / await等语法了,所以我们可以放心的直接使用async / await,而不需要babel等编译 包裹 首先需要配置新的package.json { "name" : "wechat" , "version" : "1.0.0" , ...