在解决了其中包含嵌套承诺的承诺后执行代码
Executing a code after a promise with nested promises inside it is resolved
我有如下js代码结构;
Promise_1.then(function(){
for(){
Promise2.then(function(){
...
})
}
}).then(
Promise_3.then(function(){
for(){
Promise4.then(function(){
...
})
}
})
).then(
function(){
// SOME CODE
}
)
我想在上述承诺得到解决后执行一些代码。但是在上述承诺得到解决之前,SOME CODE 正在执行。我知道我可以在 setTimeout()
中附上一些代码,这将解决 SO 上其他答案所建议的问题,但我认为这不是一个好主意。我正在处理的实际代码如下;
user_xp = 0
connections_blocks.methods.get_deposit_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
}, function (err, result) {
deposit_blocks = result
console.log(deposit_blocks)
deposit_blocks = deposit_blocks.split(",")
deposit_blocks.splice(0, 1)
for (i_ in deposit_blocks) {
console.log(deposit_blocks[i_])
user_xp + new_web3.eth.getBlock(deposit_blocks[i_]).then(function (deposit_block) {
user_xp = user_xp + deposit_block.gasUsed
console.log(user_xp)
})
}
}).then(
connections_blocks.methods.get_send_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
}, function (err, result) {
send_blocks = result
console.log(send_blocks)
send_blocks = send_blocks.split(",")
send_blocks.splice(0, 1)
for (i_ = 0; i_ < send_blocks.length; i_ = i_ + 2) {
console.log(send_blocks[i_])
user_xp + new_web3.eth.getBlock(send_blocks[i_]).then(function (send_block) {
user_xp = user_xp + send_block.gasUsed
console.log(user_xp)
})
}
})).then(
setTimeout(function () {
console.log(user_xp)
xp = document.getElementById('xp')
xp.innerHTML = "XP:" + user_xp
},1000)
)
在上面的代码中,我只是使用 setTimeout()
来解决我的问题。但我希望代码仅在上述承诺得到解决时自动执行。有什么简单的方法可以在 JS w/o 中将 promises 放入函数中并使其更复杂。
更新
我正在使用以下 web3 的函数从 solidity 的智能合约中获取数据,这实际上是 returns 对数据的承诺 promiseValue
myContract.methods.myMethod([parameters).call(options,[callback])
我假设 Promise_1 和 Promise_3 的解析将等待回调完成。如果是这种情况,这应该有效。
user_xp = 0
connections_blocks.methods.get_deposit_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
}, function (err, result) {
deposit_blocks = result
console.log(deposit_blocks)
deposit_blocks = deposit_blocks.split(",")
deposit_blocks.splice(0, 1)
// array to hold the promises
const subPromises = []
for (i_ in deposit_blocks) {
console.log(deposit_blocks[i_])
subPromises.push(new_web3.eth.getBlock(deposit_blocks[i_]))
}
// waiting for all promises to resolve
Promise.all(subPromises).then(function (deposit_block) {
user_xp = user_xp + deposit_block.gasUsed
console.log(user_xp)
})
})
.then(
connections_blocks.methods.get_send_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
}, function (err, result) {
send_blocks = result
console.log(send_blocks)
send_blocks = send_blocks.split(",")
send_blocks.splice(0, 1)
const subPromises = []
for (i_ = 0; i_ < send_blocks.length; i_ = i_ + 2) {
console.log(send_blocks[i_])
subPromises.push(
new_web3.eth.getBlock(send_blocks[i_])
)
}
Promise.all(subPromises).then(function (send_block) {
user_xp = user_xp + send_block.gasUsed
console.log(user_xp)
})
})
)
.then(function () {
console.log(user_xp)
xp = document.getElementById('xp')
xp.innerHTML = "XP:" + user_xp
})
您的代码问题包括
- .then 的参数必须是函数
- 如果你需要在循环中等待Promise,你需要将它们添加到一个数组中,然后使用promise.all等待它们全部被解决
尝试对您的 actual 代码进行以下更改 - 我假设在没有节点样式回调的情况下,函数 returns 解析为 result
将传递给节点样式回调(在此代码中删除)
(如果您稍等片刻,我会展平 promise 链 - 只是注意到它并没有达到预期的水平
user_xp = 0
return connections_blocks.methods.get_deposit_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
})
.then(function (result) {
var promises = []
deposit_blocks = result
console.log(deposit_blocks)
deposit_blocks = deposit_blocks.split(",")
deposit_blocks.splice(0, 1)
for (i_ in deposit_blocks) {
console.log(deposit_blocks[i_])
promises.push(
new_web3.eth.getBlock(deposit_blocks[i_]).then(function (deposit_block) {
user_xp = user_xp + deposit_block.gasUsed
console.log(user_xp)
})
)
}
return Promise.all(promises)
})
.then(function () {
return connections_blocks.methods.get_send_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
})
})
.then(function (result) {
var promises=[]
send_blocks = result
console.log(send_blocks)
send_blocks = send_blocks.split(",")
send_blocks.splice(0, 1)
for (i_ = 0; i_ < send_blocks.length; i_ = i_ + 2) {
console.log(send_blocks[i_])
promises.push(
new_web3.eth.getBlock(send_blocks[i_]).then(function (send_block) {
user_xp = user_xp + send_block.gasUsed
console.log(user_xp)
})
)
}
return Promise.all(promises)
})
.then(function () {
console.log(user_xp)
xp = document.getElementById('xp')
xp.innerHTML = "XP:" + user_xp
})
作为补充"bonus",相信代码可以简化为
return connections_blocks.methods.get_deposit_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
})
.then(result => Promise.all(result.split(",").slice(1).map(deposit_block => new_web3.eth.getBlock(deposit_block)
.then(deposit_block => deposit_block.gasUsed)
})
.then(gasUsed1Array => connections_blocks.methods.get_send_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
})
.then(result => Promise.all(result.split(",").slice(1).filter((v, i) => !(i%2)).map(send_blocks => new_web3.eth.getBlock(send_block)
.then(send_block => send_block.gasUsed)
)))
.then(gasUsed2Array => [...gasUsed1Array, ...gasUsed2Array])
)
.then(results => {
user_xp = results.reduce((a, b) => a + b);
console.log(user_xp)
xp = document.getElementById('xp')
xp.innerHTML = "XP:" + user_xp
})
我有如下js代码结构;
Promise_1.then(function(){
for(){
Promise2.then(function(){
...
})
}
}).then(
Promise_3.then(function(){
for(){
Promise4.then(function(){
...
})
}
})
).then(
function(){
// SOME CODE
}
)
我想在上述承诺得到解决后执行一些代码。但是在上述承诺得到解决之前,SOME CODE 正在执行。我知道我可以在 setTimeout()
中附上一些代码,这将解决 SO 上其他答案所建议的问题,但我认为这不是一个好主意。我正在处理的实际代码如下;
user_xp = 0
connections_blocks.methods.get_deposit_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
}, function (err, result) {
deposit_blocks = result
console.log(deposit_blocks)
deposit_blocks = deposit_blocks.split(",")
deposit_blocks.splice(0, 1)
for (i_ in deposit_blocks) {
console.log(deposit_blocks[i_])
user_xp + new_web3.eth.getBlock(deposit_blocks[i_]).then(function (deposit_block) {
user_xp = user_xp + deposit_block.gasUsed
console.log(user_xp)
})
}
}).then(
connections_blocks.methods.get_send_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
}, function (err, result) {
send_blocks = result
console.log(send_blocks)
send_blocks = send_blocks.split(",")
send_blocks.splice(0, 1)
for (i_ = 0; i_ < send_blocks.length; i_ = i_ + 2) {
console.log(send_blocks[i_])
user_xp + new_web3.eth.getBlock(send_blocks[i_]).then(function (send_block) {
user_xp = user_xp + send_block.gasUsed
console.log(user_xp)
})
}
})).then(
setTimeout(function () {
console.log(user_xp)
xp = document.getElementById('xp')
xp.innerHTML = "XP:" + user_xp
},1000)
)
在上面的代码中,我只是使用 setTimeout()
来解决我的问题。但我希望代码仅在上述承诺得到解决时自动执行。有什么简单的方法可以在 JS w/o 中将 promises 放入函数中并使其更复杂。
更新
我正在使用以下 web3 的函数从 solidity 的智能合约中获取数据,这实际上是 returns 对数据的承诺 promiseValue
myContract.methods.myMethod([parameters).call(options,[callback])
我假设 Promise_1 和 Promise_3 的解析将等待回调完成。如果是这种情况,这应该有效。
user_xp = 0
connections_blocks.methods.get_deposit_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
}, function (err, result) {
deposit_blocks = result
console.log(deposit_blocks)
deposit_blocks = deposit_blocks.split(",")
deposit_blocks.splice(0, 1)
// array to hold the promises
const subPromises = []
for (i_ in deposit_blocks) {
console.log(deposit_blocks[i_])
subPromises.push(new_web3.eth.getBlock(deposit_blocks[i_]))
}
// waiting for all promises to resolve
Promise.all(subPromises).then(function (deposit_block) {
user_xp = user_xp + deposit_block.gasUsed
console.log(user_xp)
})
})
.then(
connections_blocks.methods.get_send_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
}, function (err, result) {
send_blocks = result
console.log(send_blocks)
send_blocks = send_blocks.split(",")
send_blocks.splice(0, 1)
const subPromises = []
for (i_ = 0; i_ < send_blocks.length; i_ = i_ + 2) {
console.log(send_blocks[i_])
subPromises.push(
new_web3.eth.getBlock(send_blocks[i_])
)
}
Promise.all(subPromises).then(function (send_block) {
user_xp = user_xp + send_block.gasUsed
console.log(user_xp)
})
})
)
.then(function () {
console.log(user_xp)
xp = document.getElementById('xp')
xp.innerHTML = "XP:" + user_xp
})
您的代码问题包括
- .then 的参数必须是函数
- 如果你需要在循环中等待Promise,你需要将它们添加到一个数组中,然后使用promise.all等待它们全部被解决
尝试对您的 actual 代码进行以下更改 - 我假设在没有节点样式回调的情况下,函数 returns 解析为 result
将传递给节点样式回调(在此代码中删除)
(如果您稍等片刻,我会展平 promise 链 - 只是注意到它并没有达到预期的水平
user_xp = 0
return connections_blocks.methods.get_deposit_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
})
.then(function (result) {
var promises = []
deposit_blocks = result
console.log(deposit_blocks)
deposit_blocks = deposit_blocks.split(",")
deposit_blocks.splice(0, 1)
for (i_ in deposit_blocks) {
console.log(deposit_blocks[i_])
promises.push(
new_web3.eth.getBlock(deposit_blocks[i_]).then(function (deposit_block) {
user_xp = user_xp + deposit_block.gasUsed
console.log(user_xp)
})
)
}
return Promise.all(promises)
})
.then(function () {
return connections_blocks.methods.get_send_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
})
})
.then(function (result) {
var promises=[]
send_blocks = result
console.log(send_blocks)
send_blocks = send_blocks.split(",")
send_blocks.splice(0, 1)
for (i_ = 0; i_ < send_blocks.length; i_ = i_ + 2) {
console.log(send_blocks[i_])
promises.push(
new_web3.eth.getBlock(send_blocks[i_]).then(function (send_block) {
user_xp = user_xp + send_block.gasUsed
console.log(user_xp)
})
)
}
return Promise.all(promises)
})
.then(function () {
console.log(user_xp)
xp = document.getElementById('xp')
xp.innerHTML = "XP:" + user_xp
})
作为补充"bonus",相信代码可以简化为
return connections_blocks.methods.get_deposit_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
})
.then(result => Promise.all(result.split(",").slice(1).map(deposit_block => new_web3.eth.getBlock(deposit_block)
.then(deposit_block => deposit_block.gasUsed)
})
.then(gasUsed1Array => connections_blocks.methods.get_send_blocks(current_email).call({
from: new_web3.eth.Contract.defaultAccount
})
.then(result => Promise.all(result.split(",").slice(1).filter((v, i) => !(i%2)).map(send_blocks => new_web3.eth.getBlock(send_block)
.then(send_block => send_block.gasUsed)
)))
.then(gasUsed2Array => [...gasUsed1Array, ...gasUsed2Array])
)
.then(results => {
user_xp = results.reduce((a, b) => a + b);
console.log(user_xp)
xp = document.getElementById('xp')
xp.innerHTML = "XP:" + user_xp
})