即使返回后函数仍继续执行

时间:2020-07-11 21:53:26

标签: javascript mongoose es6-promise

我的问题很简单,当我运行以下代码并检查数据库时,我发现用户已成功删除,这意味着User.findOneAndDelete已执行,promise已兑现,我希望看到{{1 }};但是,我得到的{ success: 'user_deleted' }仅在不存在用户的情况下才发生,在这里不是这种情况,因为IF块中的代码是根据我在数据库中的观察执行的。

{ error: 'user_not_found' }

现在要解决此问题,我尝试添加一个User.exists({ username}).then(exists => { if (exists) { User.findOneAndDelete({ username }).then(() => { res.json({ success: 'user_deleted' }); return; } ).catch(err => { res.json({ error: 'user_delete_fail' }); return; }) }; res.json({ error: 'user_not_found' }) return; }); 语句,而不是之前执行的隐式方式,它按预期方式工作,并且在响应中得到了“ {success:'user_deleted'}”。 / p>

else

我的问题是:为什么会发生这种现象?为什么执行已经跳到函数底部?以及为什么当它到达函数底部并做出响应时,如何发生删除操作以及如何在数据库中删除用户,我在这里很困惑。

编辑:当我将父函数转换为User.exists({ username}).then(exists => { if (exists) { User.findOneAndDelete({ username }).then(() => { res.json({ success: 'user_deleted' }); return; } ).catch(err => { res.json({ error: 'user_delete_fail' }); return; }) } else { res.json({ error: 'user_not_found' }) return; }; }); 函数并在数据库操作上使用await时,它的行为也符合预期。

2 个答案:

答案 0 :(得分:2)

您的代码存在问题,是最后一次res.json({ error: 'user_not_found' })调用。

如果仔细看,由于内部查询是异步的,因此甚至在内部删除查询被触发之前,该行也会被触发。

因此,在第一种情况下,无论用户是否存在,该函数总是返回响应。

在代码块中放入其他内容基本上会执行either this or that逻辑,因此如果用户存在,res.json({ error: 'user_not_found' })将永远不会被调用。

编辑:使用异步等待的备用代码

在这种情况下使用async-await会更有意义,因为它可以简化代码,请检查下面的代码,这些代码应该完全满足您的需要而无需使用else

它还避免了嵌套,从而简化了代码

User.exists({ username }).then(async exists => {
    try {
        if (exists) {
            // this await will remove the need of inner promise chaining
            await User.findOneAndDelete({ username });
            res.json({ success: 'user_deleted' });
        }
        // in this case, this will no longer be performed before delete query
        res.json({ error: 'user_not_found' });
    } catch (error) {
        res.json({ error: 'user_delete_fail' });
    }
});

PS-对于async-await API,您可以有类似的User.exists,只要其父功能标记为async

我希望这会有所帮助。

答案 1 :(得分:1)

findOneAndDelete返回一个Promise,它将不会阻止其余代码的执行(如您所指出的,函数为async并且等待它时除外)。此外,您不会从if分支返回(return内部的then仅从then中的回调返回),因此外部的其余代码将以任何一种方式执行。它可能仅在您等待时(没有return)才有效,因为响应已在该点发送。