【问题标题】:Why does async / await function run twice?为什么 async / await 函数运行两次?
【发布时间】:2019-04-13 18:13:07
【问题描述】:

我正在使用 expressnode.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?

【问题讨论】:

  • 因为你的浏览器发送了两个请求。

标签: javascript node.js express async-await sequelize.js


【解决方案1】:

每当您打开网页时,标签的左上角都会出现一个小图标,其中包含该页面的徽标。该图标从theserver/favicon.ico 加载,如果返回错误,则图标保持为空,否则返回的照片用作图标。还有其他这样的保留文件,例如norobots.txtmanifest.json。因此,将变量 url 部分放在主级别是一个坏主意。这个:

 router.get('/:myId'

捕捉一切。相反,您应该将其移至子路径:

 router.get('/id/:myId'

【讨论】:

  • 天啊!我为此浪费了多少时间((感谢您的解释。现在它可以正常工作了!
【解决方案2】:

因为使用路由参数/:myId,您也将提供/favicon 请求。所以这是 2 个请求。

【讨论】:

  • 我应该怎么做才能只处理一个请求?
  • 首先使用参数是一种不好的做法。因为你会满足每一个请求。您应该始终从静态部分开始您的路线。 /static-part/:my-param 或者你可以用一些正则表达式来验证你的 url/param,但这非常昂贵。
猜你喜欢
  • 2018-05-10
  • 2021-05-15
  • 1970-01-01
  • 2019-02-26
  • 1970-01-01
  • 2023-01-17
  • 1970-01-01
  • 2020-07-31
  • 1970-01-01
相关资源
最近更新 更多