回调不能正确调用,如果该参数是一个绑定功能
问题描述:
当一个函数需要一个回调的PARAM,我想这是有意义的提供这样回调不能正确调用,如果该参数是一个绑定功能
function invokeCb(cb){
cb();
}
function test(x){
console.log(x)
}
const para="xyz";
invokeCb(test.bind(null,para)) //(1)
invokeCb(()=>{test(para)}) //(2)
我看不到绑定功能(1)
有任何问题。然而,当它来到真实的世界,我会遇到一些意外的行为
下面是一个例子,在redux
store.subscribe(
()=>{(saveState.bind(null,store.getState()))()}
)
能正常工作,而
store.subscribe(saveState.bind(null,store.getState()))
不能正确,即store.getState()
似乎从未正确调用
如果您需要更多上下文。这里:https://egghead.io/lessons/javascript-redux-persisting-the-state-to-the-local-storage
也许我错过了两种形式之间的细微差别,任何人都可以指出它吗?
答
的差异
- 在其
store.getState()
评估 - 返回值的时候(用括号没有
return
,你压抑它)
let data = "abc";
function invokeCb(cb){
data = "xyz";
console.log(cb());
}
function test(x){
console.log(x);
return x.toUpperCase();
}
invokeCb(test.bind(null, data)); // abc ABC
invokeCb(()=>{ test(data); }); // xyz undefined
答
经过一番调查,我找出了错误的真正原因!
下面是代码以证明:
function invokeCb(cb){
cb();
}
function test(x){
console.log(x)
}
let counter=0;
function getData(){
return ({counter:counter++})
}
const bindVersion=test.bind(null,getData())
const invokeVersion=()=>test(getData())
//first time
invokeCb(bindVersion) //{counter:0}
invokeCb(invokeVersion) //{counter:1}
//second time
invokeCb(test.bind(null,getData())) //{counter:0}
invokeCb(()=>{test(getData())}) //{counter:2}
//third time
invokeCb(test.bind(null,getData())) //{counter:0}
invokeCb(()=>{test(getData())}) //{counter:3}
说明:
- 当使用
bind
版本,参数为固定。即一旦 它是bound
它不能被改变。另一方面,当函数被直接调用时, 参数是动态,即,它可以随时得到更新的数据
结论:
NEVER绑定动态参数的函数
对我来说,情况state
是每次immutable
在redux
,store.getState()
return
一个新的参考,使用bind
,它总是得到第一个参考
我相信你知道答案,你可以设计一个具体的例子来恶魔培养差异,我真的无法得到你的观点 – Guigui
你是正确的,问题在于'商店。getState()'读取陈旧的数据 – Guigui
@Guigui我添加了一个例子(但没有尝试) – Bergi