javascript - 尽管异步/等待,Discord bot 仍以错误的顺序发送消息
问题描述
我又遇到了这个异步编码问题,太烦人了。我想避免使用回调地狱并避免 startig withnew Promise
和 resolve 所以我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)
})
})
})
使用这个解决方法可以修复它并且像一个魅力一样工作,但我想避免这个回调地狱,因为它显然是不好的做法。
我会很感激任何帮助。
解决方案
脚本中的错误很少:
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()
推荐阅读
- python - 根据下一行的列值计算数据框中的新列值
- python - to_dict() 函数从数据帧而不是 OrderedDict 创建一个列表
- scrapy - 当我使用scrapy的管道进行数据持久化时,pymysql在我想关闭连接时提示'NoneType' object has no attribute'close'
- python - 如何使用占位符在 Flask 中编写查询以连接表
- html - ModelForm Django中的ImageField问题,request.FILES为空
- c# - JWT 和 2FA 工作流程
- javascript - 使用两个不同的值作为范围填充 Javascript 中的对象数组
- java - How to Build Graph Using Java Stream API
- python - Odoo api.depends 装饰器问题
- python - 如何在 Python Odoo 中重置 SQL 约束