Web3.js中以太坊合约交易挖矿后带参数回调的实现问题
callWhenMined函数 当然可以实现支持传递回调参数的callWhenMined!你给出的写法存在语法错误,不过我们可以用几种JavaScript常用技巧来完美解决这个问题。
先分析你遇到的问题
你尝试用callWhenMined(txHash, getTokenBalance('testID', 1))调用时,会直接执行getTokenBalance('testID', 1),并把这个函数的执行结果传给callWhenMined作为回调。因为getTokenBalance本身没有返回值(或者返回的是余额字符串),所以callWhenMined拿到的callback不是一个函数,自然会触发“callback不是函数”的错误。
解决方案1:用匿名函数包裹回调(无需修改原有callWhenMined)
最简单的方式是在调用时用匿名函数把带参数的回调包裹起来,这样传给callWhenMined的是一个真正的函数,等交易确认后再执行带参数的getTokenBalance:
// 在buyTokens里这样调用 callWhenMined(txHash, function() { getTokenBalance('testID', account); });
这个方法不需要修改你原来的callWhenMined函数,代码改动最小,适合快速解决问题。
解决方案2:修改callWhenMined支持任意回调参数(更灵活)
如果希望callWhenMined本身就支持传递回调参数,可以利用ES6的剩余参数(Rest Parameters)和扩展运算符(Spread Operator)来实现,让它能处理任意数量的回调参数:
function callWhenMined(txHash, callback, ...callbackArgs) { web3.eth.getTransactionReceipt(txHash, function(error, rcpt) { if(error) { console.error(error); } else { if(rcpt == null) { setTimeout(function() { // 递归调用时要把回调参数一起传递 callWhenMined(txHash, callback, ...callbackArgs); }, 500); } else { document.getElementById("transaktion").innerText = ""; // 把参数展开传给回调函数 callback(...callbackArgs); } } }) }
然后调用的时候直接把回调函数和它需要的参数依次传入即可:
// 在buyTokens里这样调用 callWhenMined(txHash, getTokenBalance, 'testID', account);
这种方式扩展性更强,不管你的回调需要多少个参数,都能完美支持,代码也更整洁。
为什么你原来的写法不可行
你写的function callWhenMined(txHash, callback(param1, param2, ...))是无效的JavaScript语法,函数的参数只能是变量标识符,不能是带参数的函数调用表达式。所以这种写法根本无法被JS引擎解析,自然不能工作。
内容的提问来源于stack exchange,提问作者Doodle

