node.js绑定回调问题

时间:2018-06-13 16:16:06

标签: node.js bind

我有以下代码:

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来解决,但我找不到正确的方法来实现它并保持实际设计

添加const修复问题,但我想找到一种更优雅/通用的方法来解决问题

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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

&#13;
&#13;
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});
}
&#13;
&#13;
&#13;