node.js - 将 setTimeout 与递归 promise 一起使用

标签 node.js promise

我有以下代码等待在以太坊区 block 链上挖掘交易。

function waitForMinedTransaction(txHash, tries = 1) {
  return new Promise(function(resolve, reject) {
    web3.eth.getTransactionReceipt(txHash, function(err, res) {
      if (err) reject(err)
      if (res) resolve(res)

      // nothing yet (retry in 10 sec..)
      console.log(`Attempt #${ tries }...`)
      if (tries > 60) reject("max_tries_exceeded")
      setTimeout(function() { return waitForMinedTransaction(txHash, tries + 1) }, 10000)
    })
  })
}

问题是当交易被挖掘时(例如在 10 次尝试之后),它永远不会得到解决。我确定这与 setTimeout 和 promise 链有关(其中 promise 是 returned 而不是 resolve/拒绝当前的 promise )但需要一些关于修复它的指示。

最佳答案

我建议将链接逻辑嵌入 promise 构造函数回调。

还要确保当您解决或拒绝时,您退出该函数以避免执行其余代码。所以在调用 resolvereject 之前放置一个 return ,并不是说返回值有任何意义,只是为了确保其余的该函数的代码未执行:

function waitForMinedTransaction(txHash) {
    return new Promise(function(resolve, reject) {
        (function attempt(triesLeft) {
            web3.eth.getTransactionReceipt(txHash, function(err, res) {
                if (err) return reject(err);
                if (res) return resolve(res);
                if (!triesLeft) return reject("max_tries_exceeded");
                console.log(`No result. Attempts left: #${ triesLeft }...`);
                setTimeout(attempt.bind(null, triesLeft-1), 10000);
            });
        })(60); // number of retries if first time fails
    });
}

如果你更喜欢在链中有新的 promise (就像你试图做的那样),那么诀窍就是用链式 promise 来解决,即用链式调用的返回值:

function waitForMinedTransaction(txHash, triesLeft = 60) {
    return new Promise(function(resolve, reject) {
        getTransactionReceipt(txHash, function(err, res) {
            if (err) return reject(err);
            if (res) return resolve(res);
            console.log(`No result. Attempts left: #${ triesLeft }...`);
            if (!triesLeft) return reject("max_tries_exceeded");
            setTimeout(_ => {
                resolve(waitForMinedTransaction(txHash, triesLeft-1));
            }, 10000);
        });
    });
}

关于node.js - 将 setTimeout 与递归 promise 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48337362/

相关文章:

node.js - 在 OAuth2 身份验证调用和重定向调用之间传递值

node.js - 使用 Electron 构建 Node ibm_db 包时遇到问题

javascript - 在所有其他 promise 之前等待 1 个 promise

jquery - 等待 jQuery.when ajax 请求

node.js - Phonegap 推送通知 + Node gcm : group notifications

node.js - Node JS 广播(音频流)

javascript - Passport 出现 CORS 错误 LinkedIn 策略

javascript - 然后在 nativescript 中获取后就无法工作

angularjs - 停止 Angular-ui-router 导航,直到 promise 得到解决

javascript - 将 promise 添加到我的 Kendo 网格的循环中