У меня есть следующая структура кода JS;

Promise_1.then(function(){ for(){ Promise2.then(function(){ ... }) } }).then( Promise_3.then(function(){ for(){ Promise4.then(function(){ ... }) } }) ).then( function(){ // 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_ {amp}lt; 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 без добавления обещаний в функции и усложнения этого.

ОБНОВИТЬ

Я использую следующую функцию web3 для извлечения данных из умного контракта солидности, который на самом деле возвращает обещание с данными в качестве promiseValue

myContract.methods.myMethod ([параметры) .call (опции, [вызов])

Проблемы с вашим кодом включают

  1. аргументы .then должны быть функциями
  2. если вам нужно дождаться выполнения обещаний в цикле, вам нужно добавить их в массив и затем использовать promise для того, чтобы дождаться их разрешения.

Попробуйте внести следующие изменения в ваш реальный код — я предполагаю, что без обратного вызова в стиле узла функция возвращает обещание, которое разрешается до result , который будет передан обратному вызову в стиле узла (который удален в этом коде)

(если вы подождете некоторое время, я сгладю цепочку обещаний — просто заметил, что она не такая плоская, как могла бы быть

 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_ {amp}lt; 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 }) 

Как дополнительный «бонус», я считаю, что код может быть упрощен до

 return connections_blocks.methods.get_deposit_blocks(current_email).call({ from: new_web3.eth.Contract.defaultAccount }) .then(result ={amp}gt; Promise.all(result.split(",").slice(1).map(deposit_block ={amp}gt; new_web3.eth.getBlock(deposit_block) .then(deposit_block ={amp}gt; deposit_block.gasUsed) }) .then(gasUsed1Array ={amp}gt; connections_blocks.methods.get_send_blocks(current_email).call({ from: new_web3.eth.Contract.defaultAccount }) .then(result ={amp}gt; Promise.all(result.split(",").slice(1).filter((v, i) ={amp}gt; !(i%2)).map(send_blocks ={amp}gt; new_web3.eth.getBlock(send_block) .then(send_block ={amp}gt; send_block.gasUsed) ))) .then(gasUsed2Array ={amp}gt; [...gasUsed1Array, ...gasUsed2Array]) ) .then(results ={amp}gt; { user_xp = results.reduce((a, b) ={amp}gt; a   b); console.log(user_xp) xp = document.getElementById('xp') xp.innerHTML = "XP:"   user_xp }) 

Я предполагаю, что решение 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_ {amp}lt; 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 }) 
FUBAR

новый участник этого сайта. Будьте внимательны, спрашивая разъяснения, комментируя и отвечая. Проверьте наш

Правила поведения

,