在express中使用async middleware

简介: ## 普通middleware ``` const express = require('express') const app = express() const port = 3000 app.use('/normal', (req, res) => res.send('Hello World!')) app.listen(port, () => console.log

普通middleware

const express = require('express')
const app = express()
const port = 3000

app.use('/normal', (req, res) => res.send('Hello World!'))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

文艺middleware (async)

const express = require('express')
const app = express()
const port = 3000

app.use('/art', async (req, res) => {
  await new Promise((resolve, reject) => {
    setTimeout(resolve, 1000)
  })
  res.send('Bonjour le monde!')
})

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

万一middleware里报错了怎么办

增加一个4参数的中间件作为error handler,当然express也有一个默认的handler

const express = require('express')
const app = express()
const port = 3000

app.use('/normal', (req, res) => res.send('Hello World!'))
app.use('/normal-error', (req, res, next) => {
  throw new Error('some error')
})

app.use((err, req, res, next) => res.send('error detected: ' +  err.message))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

async middleware里的报错也这么处理?

答案是No

const express = require('express')
const app = express()
const port = 3000

app.use('/art', async (req, res) => {
  await new Promise((resolve, reject) => {
    setTimeout(resolve, 1000)
  })
  res.send('Bonjour le monde!')
})
app.use('/2b-error-1', async (req, res) => {
  await new Promise((resolve, reject) => {
    setTimeout(() => reject('another error 1'), 1000)
  })
})
app.use('/2b-error-2', async (req, res) => {
  await Promise.resolve().then(() => {
    throw new Error('another error 2')
  })
})

app.use((err, req, res, next) => res.send('error detected: ' +  err.message))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

如果只这样写的话,浏览器里不会有任何返回,而你会在终端里得到下面的报错:
image.png

image.png

正确处理async middleware里的报错

const express = require('express')
const app = express()
const port = 3000

app.use('/art', async (req, res) => {
  await new Promise((resolve, reject) => {
    setTimeout(resolve, 1000)
  })
  res.send('Bonjour le monde!')
})
app.use('/art-error-1', async (req, res, next) => {
  try {
    await new Promise((resolve, reject) => {
      setTimeout(() => reject(new Error('another error 1')), 1000)
    })
  } catch (e) {
    next(e)
  }
})
app.use('/art-error-2', async (req, res, next) => {
  await Promise.resolve().then(() => {
    throw new Error('another error 2')
  }).catch(next)
})

app.use((err, req, res, next) => res.send('error detected: ' +  err.message))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

处理的办法就是catch住异步操作中可能会抛出的错误,这里其实没有新的内容,在express的文档里已经说了必须捕获异步操作中的错误:

You must catch errors that occur in asynchronous code invoked by route handlers or middleware and pass them to Express for processing.

每个异步操作都如此try/catch,太麻烦了

解决办法是写一个高阶函数asyncMiddleware,在这个函数里面给传进来的middleware自动加上catch方法。

const express = require('express')
const app = express()
const port = 3000

app.use('/art', async (req, res) => {
  await new Promise((resolve, reject) => {
    setTimeout(resolve, 1000)
  })
  res.send('Bonjour le monde!')
})

// 重点
function asyncMiddleware(fn) {
  return (req, res, next) => fn(req, res, next).catch(next)
}
app.use('/art-error-1', asyncMiddleware(async (req, res, next) => {
  await new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error('another error 1')), 1000)
  })
}))
app.use('/art-error-2', asyncMiddleware(async (req, res, next) => {
  await Promise.resolve().then(() => {
    throw new Error('another error 2')
  })
}))

app.use((err, req, res, next) => res.send('error detected: ' +  err.message))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

如果不确定参数是否一定为async function,可以使用Promise.resolve(fn(req, res, next))

相关文章
|
JSON 前端开发 中间件
axios基本使用,express中间件
axios基本使用,express中间件
|
2月前
实际项目中选择使用async/await和Generators
最终的选择应该根据项目的具体情况、团队的能力和偏好等因素进行综合权衡。你在实际项目中是如何做出选择的呢?是否有一些具体的经验或案例可以分享?我们可以进一步交流和探讨,以便更好地应对实际项目中的挑战。
|
6月前
|
前端开发 JavaScript
js【详解】async await
js【详解】async await
40 0
|
8月前
|
JSON 中间件 API
在 Express.js 中处理 GET 请求
在 Express.js 中处理 GET 请求
|
开发框架 JavaScript 前端开发
koa和express有哪些不同?
koa和express有哪些不同?
108 1
Error:express-session deprecated undefined resave option; provide resave option app.js:17:10
Error:express-session deprecated undefined resave option; provide resave option app.js:17:10
Error:express-session deprecated undefined resave option; provide resave option app.js:17:10
|
8月前
|
JavaScript 前端开发
如何在 TypeScript 中使用 async/await?
如何在 TypeScript 中使用 async/await?
237 0
|
8月前
|
消息中间件 中间件 API
什么是 Koa2?它与 Express 有什么区别?
什么是 Koa2?它与 Express 有什么区别?
301 0
|
人工智能 自然语言处理 JavaScript
vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in created hook: “TypeError: Object(...) is not a func
vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in created hook: “TypeError: Object(...) is not a func
130 0
|
前端开发 JavaScript
了解js中async-await
了解async异步函数如何使用并且使用中的注意点
182 0
了解js中async-await