【问题标题】:Does node.js allow promises to be run without any kind of await/expected fulfillment?node.js 是否允许在没有任何等待/预期履行的情况下运行承诺?
【发布时间】:2021-01-12 17:58:05
【问题描述】:

我喜欢浏览 Discord 标签并尽可能解决问题。我在 Python 方面相当流利,但只在 Javascript 方面过得去,但有时我确实会大吃一惊。
Discord.py 库有许多必须等待的功能。否则将无法运行。
Discord.js 库为不同的事物返回了许多 Promise,当我写涉及这些的答案时,我很自然地添加了 await。我还查找了 tutorial 以查看在 Discord.js 中编写 async/await 的最佳实践。
此外,添加 await 要求我使我的事件处理程序异步,非理性地强化了我的信念,这些 await 语句需要存在。

client.on('message', async message => {
   await message.member.edit({mute: true})
});

这一切都很好,我愚蠢地开始推荐其他人也这样做。但是,在阅读问题和编写答案时,我偶然发现了一些令我困惑的东西。

client.on('message', message => {
        let memberArray = [message.member];
        memberArray.forEach(member => member.edit({mute: true}));
        console.log("Do something after promised mute");
});

这段代码,没有异步函数,也没有等待的承诺,仍然运行。这对我来说似乎很奇怪(如果代码可以执行,看起来是同步的,没有它,等待的意义何在?)。

继续困惑,我可以使这个函数异步并在不等待承诺的情况下继续运行它。唯一会导致错误的是同步函数中的 await 语句。

另一种可能性是这个不安全并且会在生产中引起问题,但是由于我的测试机器人一次只与一个用户(我)交互做一件事,我不能看到问题。 Node.js 是否让我运行错误代码而不警告我?我是否过度考虑/过度设计了一个非问题?航空食品有什么问题?

【问题讨论】:

  • 第二个 sn-p 中的 console.log() 不会等待 member.edit() 承诺解决。
  • 等待承诺是可选的。这样做有充分的理由:一个是您可能决定解雇并忘记,另一个是您可能想要收集多个 Promise 并在它们上使用 promise.all。

标签: javascript node.js promise async-await discord.js


【解决方案1】:

在 Javascript 中没有要求 await 一个承诺。如果你想进行一个异步调用,它返回一个 Promise 并在它完成时忽略它,你可以做到这一点。这有时被称为“一劳永逸”。我经常通过关闭文件来执行此操作,例如,因为当文件最终关闭时,我无事可做。

需要从可能发生的 Promise 中捕获任何拒绝。因此,如果您的承诺有任何被拒绝的机会,您至少需要在await 周围使用.catch()try/catch

在这个特定的例子中:

client.on('message', async message => {
   await message.member.edit({mute: true})
});

这里不需要使用await,事实上,它根本没有任何用处。它不会停止或暂停任何东西。如果message.member.edit({mute: true}) 返回一个promise,那么await 将暂停执行该回调并立即将一个promise 返回到触发事件的事件系统,但nodejs 中的其他事件将继续得到处理,这是最后一行无论如何,该功能,所以await实际上并没有完成任何事情。

如果message.member.edit({mute: true}) 返回一个promise,并且您希望在回调中执行其他操作之前等待所有这些都完成,那么您将不得不使用for 循环连续处理它们或处理它们并行并使用Promise.all() 跟踪它们:

// process serially with for loop and await  
client.on('message', async message => {
    try {
        let memberArray = [message.member];
        for (let member of memberArray) {
            await member.edit({mute: true});
        }
        console.log("Do something after promised mute is completed");
     } catch(e) {
        // catch any rejections
        console.log(e);
     }
});

// process in parallel with Promise.all()
client.on('message', async message => {
    try {
        let memberArray = [message.member];
        await Promise.all(memberArray.map(member => member.edit({mute: true})));
        console.log("Do something after promised mute is completed");
     } catch(e) {
        // catch any rejections
        console.log(e);
     }
});

现在,如果 member.edit({mute: true}) 不是异步的并返回与异步操作相关联的承诺,那么所有这些都没有实际意义,因为在任何情况下都不需要或有用 await

【讨论】:

猜你喜欢
  • 2020-07-08
  • 1970-01-01
  • 1970-01-01
  • 2017-05-08
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多