【问题标题】:Discord bot sends message in the wrong order despite async/await尽管异步/等待,Discord bot 仍以错误的顺序发送消息
【发布时间】:2021-02-28 21:00:48
【问题描述】:

我又遇到了这个异步编码问题,太烦人了。我想避免使用回调地狱并避免使用new Promise 开始并解决,所以我改用async/await

目标
我希望我的不和谐机器人按照定义的顺序在频道中一个接一个地吐出每个服务器状态。

问题
当然,输出的顺序是错误的。我知道每个服务器响应的速度是不同的。尽管使用了async/await,但它仍然无法按我的意愿工作,这让我很困惑。好像我用错了,就是不知道在哪里。我尝试使用forEach 循环迭代数组并使用Promise.all(),但它仍然不是正确的顺序。

我的代码 (MCVE)
我正在使用模块 net 来请求服务器状态,而对于这个 MCVE,我使用了 3 个随机主机。

const 
    status = require('net'),
    hosts = [
        ['Server #1', 'google.com', 80], 
        ['Server #2', 'jhfg87ed4.com', 80], // fake, just for response check
        ['Server #3', 'stackoverflow.com', 80]
    ]

const server = async (id, cb)=> {
    let host = hosts[id]
    const sock = new status.Socket()
    sock.setTimeout(2500)
    sock.on('connect', ()=> {
        cb(host[0]+': Up.')
        sock.destroy()
    }).on('error', e=> {
        cb(host[0]+': Down: '+e.message)
    }).on('timeout', e=> {
        cb(host[0]+' Down: timeout')
    }).connect(host[2], host[1])
}

async function results() { // wrong ?
    await server(0, cb => channel.send(cb))
    await server(1, cb => channel.send(cb))
    await server(2, cb => channel.send(cb))
}

输出:(随机顺序)

results() // not the order I wanted

Server #3: Up.
Server #1: Up.
Server #2: Down: getaddrinfo ENOTFOUND jhfg87ed4.com

解决方法(不好的做法)

server(0, cb => {
    channel.send(cb)
    server(1, cb => {
        channel.send(cb)
        server(2, cb => {
            channel.send(cb)
        })
    })
})

使用此解决方法可以修复它并像魅力一样工作,但我想避免这种回调地狱,因为这显然是不好的做法。

我将不胜感激。

【问题讨论】:

  • server() 不返回承诺

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


【解决方案1】:

脚本中的错误很少:

  • async 不调用 await 是没有用的
  • 通常使用回调代替await,不能同时使用两者
  • 通用回调接口是callback(error, data),所以你应该遵循这个模式

所以你的脚本应该更新如下。

请注意,这是一个不管理错误的快速解决方案! (又名error 事件)


const status = require('net')
const util = require('util')

const hosts = [
  ['Server #1', 'google.com', 80],
  ['Server #2', 'jhfg87ed4.com', 80], // fake, just for response check
  ['Server #3', 'stackoverflow.com', 80]
]

function server (id, cb) {
  const host = hosts[id]
  const sock = new status.Socket()
  sock.setTimeout(2500)
  sock
    .on('connect', () => {
      cb(null, host[0] + ': Up.') // null as first parameter that is error
      sock.destroy()
    })
    .on('error', e => {
      cb(new Error(host[0] + ': Down: ' + e.message))
    })
    .on('timeout', e => {
      cb(new Error(host[0] + ' Down: timeout'))
    })
    .connect(host[2], host[1])
}

const serverPromise = util.promisify(server)

async function results () {
  let res = await serverPromise(0)
  console.log(res)
  try {
    res = await serverPromise(1)
    console.log(res)
  } catch (error) {
    console.log(error)
  }
  res = await serverPromise(2)
  console.log(res)
}

results()

【讨论】:

  • 抱歉,迟来的回复。非常感谢我已经以某种方式修复了它。是的,忘记了回调的(error, data) 模式,我没有想到这一点。仍然非常感谢您的回答和提示。
猜你喜欢
  • 2022-01-09
  • 1970-01-01
  • 2012-12-23
  • 2020-08-25
  • 2020-12-01
  • 2021-03-02
  • 2021-01-12
  • 2021-06-05
  • 2019-06-26
相关资源
最近更新 更多