Цепные обещания звонков - PullRequest
1 голос
/ 07 марта 2019

Мне нужно последовательное выполнение этих трех

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>, но оказалось, что это неправильно.

Ответы [ 4 ]

2 голосов
/ 07 марта 2019

Полагаю, 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)
    });
})

Редактировать на основе предложения TJ

В этом случае вам не нужно 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 голос
/ 07 марта 2019

С точки зрения стиля, вам лучше не смешивать обратные вызовы и асинхронное / ожидание с точки зрения последовательного потока.Чтобы использовать функции стиля обратного вызова и объединить их с помощью async / await, вы можете заключить их в обещания, чтобы «спрятать» обещания:

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
0 голосов
/ 07 марта 2019

Я подозреваю, web3.eth.getCoinbase не возвращает обещание, поскольку вы передаете ему обратный вызов.await ожидает только обещаний .

Так что вам, вероятно, нужно обернуть этот API в обещание, что означает, что initAccount не обязательно должно быть функцией async, как этоэто одна из редких ситуаций, когда вам нужно new Promise:

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

    web3.eth.getCoinbase(function(err, account) {
      if (err !== null) {
        reject(err);
      } else {
        App.account = account;
        console.log('Account: ' + App.account);
      }
    });
  });
}

Отдельно, если bindEvents и render выполняют свою работу синхронно, вы обычно помещаете их в один и тот же обработчик then:

return App.initAccount().then(() => {
  App.bindEvents();
  App.render();
});
0 голосов
/ 07 марта 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...