Node.js绑定回调问题



我有以下代码:

let bindings = 
{
on : (messageName,callback) =>
{
bindings[messageName] = callback
}
}

bindings.on('test',(params) =>
{
setTimeout( () =>
{
console.log("call id " , params.callId)
},~~(Math.random()*100))
})
let data = {callId : 1 }

for (let i=0;i<5;i++)
{
bindings['test'](data)
data.callId++
}

它产生输出

call id 6
call id 6
call id 6
call id 6
call id 6
call id 6

我知道这个问题可以通过绑定 https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Function/bind 来解决,但我找不到正确的方法来实现它并保持实际设计

添加一个常量可以解决问题,但我想找到一种更优雅/通用的方式来解决问题

bindings.on('test',(params) =>
{
const callId = params.callId 
setTimeout( () =>
{
console.log("call id " , callId)
},~~(Math.random()*100))
})

它不是关于事件逻辑的实现,而是关于使用循环更新的引用调用它。

由于内部setTimeout,该实现是异步执行,因此调用循环在执行第一个事件逻辑之前完全执行。因此,由于输入params是对对象data的引用,当循环完成时,callId值现在是6,当被任何异步调用引用时,该值将是该值。

本质上,for循环是排队 5 个异步操作,其中每个操作都使用相同的引用对象,data.循环还会为每次迭代更新data对象的属性值。由于 JavaScript 处理异步操作的方式,循环将在任何异步操作开始之前完成,因为它仍然遵循脚本的初始同步执行。

解决此问题的一种方法是为每个循环迭代创建一个新的输入对象:

let bindings = {
on: (messageName, callback) => {
bindings[messageName] = callback
}
}
bindings.on('test', (params) => {
setTimeout(() => {
console.log("call id ", params.callId)
}, ~~(Math.random() * 100));
});
for (let i = 0; i < 5; i++) {
bindings['test']({callId: i + 1});
}

相关内容

  • 没有找到相关文章