连锁承诺电话

时间:2019-03-07 12:51:25

标签: javascript asynchronous promise

我需要连续执行这三个

return App.initAccount().then(App.bindEvents).then(App.render);

而App.initAccount():

  initAccount: async function() {

    console.log('Initializing account...');

    await web3.eth.getCoinbase(function(err, account) {
      if (err !== null) {
        throw err;
      }

      App.account = account;
      console.log('Account: ' + App.account);
    });
  }

和App.bindEvents(),App.render()只是普通的同步函数。 但是我在控制台中拥有什么:

Initializing account...
Binding events
Rendering
Account: ***

请解释一下如何链接这些调用,以便等到返回异步函数

UPD。根据文档,我认为web3.eth.getCoinbase()返回Promise <\ String>,但事实证明这是不正确的。

3 个答案:

答案 0 :(得分:2)

我想web3.eth.getCoinbase()不返回诺言(因此您在这里没有等待任何事情。您需要将函数调用包装在这样的诺言中:

await new Promise((resolve, reject) => {
  web3.eth.getCoinbase(function(err, account) {
      if (err !== null) {
        return reject(err)
      }

      App.account = account;
      return resolve(account)
    });
})

根据T.J建议进行编辑

在这种情况下,实际上不需要initAccount作为异步函数,可以将函数重构为:

initAccount: function() {
  return new Promise((resolve, reject) => {
    console.log('Initializing account...');

    web3.eth.getCoinbase(function(err, account) {
      if (err !== null) {
        return reject(err)
      }

      App.account = account;
      console.log('Account: ' + App.account);
      return resolve(account)
    });
  })
}

答案 1 :(得分:1)

从样式的角度来看,最好不要在顺序流方面混用回调和异步/等待。要使用回调样式函数并将其与async / await编织在一起,可以将它们包装在promise中以“隐藏” promise:

class Foo {
    initAccount() {
        return new Promise((resolve, reject) => {
            web3.eth.getCoinbase(function(err, account) {
                if (err !== null) {
                    reject(err);
                }
                resolve(account);
            });
        });
    }
}

const o = new Foo();
const account = await foo.initAccount();
// Then do bindEvents
// etc

答案 2 :(得分:0)

getCoinbase看起来不像一个返回承诺的函数。您应该将其包装为预期的行为。

手动:

await new Promise((resolve, reject) => {
  web3.eth.getCoinbase(function(err, account) {
    if (err !== null) {
      reject(err);
    }

    App.account = account;
    console.log('Account: ' + App.account);
    resolve(account);
  });
});

或使用类似this