为啥 async / await 函数运行两次?
Posted
技术标签:
【中文标题】为啥 async / await 函数运行两次?【英文标题】:Why does async / await function run twice?为什么 async / await 函数运行两次? 【发布时间】:2019-04-13 18:13:07 【问题描述】:我正在使用 express
和 node.js
应用程序。我有一个普通的路由器,它:
DB
中找到myID
,
如果myID
存在,它会尝试addVisit()
如果发生错误(可能这样的表不存在),它会捕获错误,创建新表并addVisit()
给它。
路由器代码如下:
router.get('/:myId', errorHandler(async (req, res, next) =>
console.log(req.params.myId + ' This is myID Params!');
const Domain = DomainModel(db, Sequelize);
const Click = ClickModel(db, `$req.params.myId_clicks`, Sequelize);
try
let row = await Domain.findOne( where: myId: req.params.myId );
console.log(row.myId + ' This is myID from DB');
if (row.myId)
try
await addVisit(Click, req);
res.sendStatus(200);
catch (err)
console.log(`This error fires!`);
if (err.message !== `Validation error`)
try
await db.sync();
await addVisit(Click, req);
res.sendStatus(200);
catch (err)
console.log(err);
res.sendStatus(400);
else
res.sendStatus(400);
else
console.log(`No such myId in use`);
res.sendStatus(400);
catch (err)
console.log(err);
)
但是代码运行了两次!我的console.log()
显示:
1. ==> 1231231231 This is myID Params!
2. ==> 1231231231 This is myID from DB
3. ==> This error fires!
4. ==> favicon.ico This is myID Params!
5. ==> TypeError: Cannot read property 'myID' of null
如果我注释这部分代码,它只会运行一次!
// if (err.message !== `Validation error`)
// try
// await db.sync();
// await addVisit(Click, req);
// res.sendStatus(200);
// catch (err)
// console.log(err);
// res.sendStatus(400);
//
// else
// res.sendStatus(400);
//
这是我唯一使用console.log()
的地方!这是我能够重现行为的简单示例项目。那么为什么代码会运行两次,为什么我的 params.myID 变成了 favicon.ico?
【问题讨论】:
因为你的浏览器发送了两个请求。 【参考方案1】:每当您打开网页时,标签的左上角都会出现一个小图标,其中包含该页面的徽标。该图标从theserver/favicon.ico
加载,如果返回错误,则图标保持为空,否则返回的照片用作图标。还有其他这样的保留文件,例如norobots.txt
和manifest.json
。因此,将变量 url 部分放在主级别是一个坏主意。这个:
router.get('/:myId'
捕捉一切。相反,您应该将其移至子路径:
router.get('/id/:myId'
【讨论】:
天啊!我为此浪费了多少时间((感谢您的解释。现在它可以正常工作了!【参考方案2】:因为使用路由参数/:myId
,您也将提供/favicon
请求。所以这是 2 个请求。
【讨论】:
我应该怎么做才能只处理一个请求? 首先使用参数是一种不好的做法。因为你会满足每一个请求。您应该始终从静态部分开始您的路线。/static-part/:my-param
或者你可以用一些正则表达式来验证你的 url/param,但这非常昂贵。以上是关于为啥 async / await 函数运行两次?的主要内容,如果未能解决你的问题,请参考以下文章
为啥一起运行时 async-await 比 Promise 慢得多
当循环在异步函数内部而不是相反时,为啥 Async/Await 可以正常工作?
Gulp/Typescript/Async/Await 代码不起作用 - 为啥?