Javascript 如何仅在映射中执行所有等待之后增加变量值,以便并行执行承诺?
嘿,这是一个非常基本的问题,但我遇到了问题。我有以下代码:Javascript 如何仅在映射中执行所有等待之后增加变量值,以便并行执行承诺?,javascript,node.js,async-await,web3js,Javascript,Node.js,Async Await,Web3js,嘿,这是一个非常基本的问题,但我遇到了问题。我有以下代码: var nonce = await web3.eth.getTransactionCount(fromAccount); hashes.map(async hash => { console.log(nonce) const account = await web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_1) const t
var nonce = await web3.eth.getTransactionCount(fromAccount);
hashes.map(async hash => {
console.log(nonce)
const account = await web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_1)
const transaction = await contract.methods.submitHash(hash);
const options = {
nonce: web3.utils.toHex(nonce),
to : transaction._parent._address,
data : transaction.encodeABI(),
gas : await transaction.estimateGas({from: account.address}),
gasPrice: web3.utils.toHex(web3.utils.toWei('20', 'gwei')),
};
const signed = await web3.eth.accounts.signTransaction(options, account.privateKey);
const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction);
console.log(receipt)
nonce ++}
我只想在每次执行所有等待时增加nonce,即,我想得到1,2,3,4。。作为当前值。但问题是由于异步性质,nonce在每个循环中获得相同的值,即1,1,1。。如何在每次循环执行时将其增加一个?问题在于,您正在使用
map
为循环添加。这有两个问题:
当您不使用它返回的数组时,使用map
是没有意义的(有人在某处教这种反模式,对他们的学生造成了伤害);及
map
与您的async
函数返回的承诺没有任何关系,因此所有async
函数都并行运行
使用for
循环,您不会遇到以下问题:
let nonce = await web3.eth.getTransactionCount(fromAccount);
for (const hash of hashes) {
console.log(nonce);
const account = await web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_1);
const transaction = await contract.methods.submitHash(hash);
const options = {
nonce : web3.utils.toHex(nonce),
to : transaction._parent._address,
data : transaction.encodeABI(),
gas : await transaction.estimateGas({from: account.address}),
gasPrice: web3.utils.toHex(web3.utils.toWei('20', 'gwei')),
};
const signed = await web3.eth.accounts.signTransaction(options, account.privateKey);
const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction);
console.log(receipt);
++nonce;
}
由于您的for
在await
工作的上下文中(一个async
函数,或者很快就是模块的顶层),因此它在await
表达式中等待,然后再继续其逻辑
如果工作可以并行完成,那么可以使用map
和wait Promise.all
返回数组。在map
回调中,使用nonce+index
而不是递增,因为index
对于第一个哈希将0
,对于下一个哈希将1
,等等:
// In parallel
let nonce = await web3.eth.getTransactionCount(fromAccount);
const results = await Promise.all(hashes.map(async (hash, index) => {
const thisNonce = nonce + index;
console.log(thisNonce);
const account = await web3.eth.accounts.privateKeyToAccount(process.env.PRIVATE_KEY_1);
const transaction = await contract.methods.submitHash(hash);
const options = {
nonce : web3.utils.toHex(thisNonce),
to : transaction._parent._address,
data : transaction.encodeABI(),
gas : await transaction.estimateGas({from: account.address}),
gasPrice: web3.utils.toHex(web3.utils.toWei('20', 'gwei')),
};
const signed = await web3.eth.accounts.signTransaction(options, account.privateKey);
const receipt = await web3.eth.sendSignedTransaction(signed.rawTransaction);
console.log(receipt);
}));
// If you're going to keep using `nonce`, do `nonce += results.length` here.
为什么地图没有归还?使用foreachhashes.map(异步(散列,索引)=>{…nonce=index;..}
@ErnestoAlfonso-如果工作可以并行进行,这是个不错的主意!但是每次都需要nonce+索引
,因为我们不知道nonce
的初始值。嘿,谢谢。问题不再存在了,只要尝试一下就可以了。嘿,谢谢。等待承诺。如果一个进程抛出错误会发生什么你会被取消吗?@Subik-你最好的回答就是找到一些权威信息,例如。承诺。所有人都会在第一次看到你的承诺被拒绝时拒绝承诺。没有什么会被取消,除了你提供的承诺之外,承诺之间没有任何协调。