Reputation: 401
I need a consecutive execution of these three
return App.initAccount().then(App.bindEvents).then(App.render);
whereas 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);
});
}
and App.bindEvents(), App.render() just ordinary synchronous functions. But what I've got in a console:
Initializing account...
Binding events
Rendering
Account: ***
Please, explain, how to chain these calls in order to wait until the asynchronous function is returned
UPD. According to the documentation I thought web3.eth.getCoinbase() returns a Promise<\String>, but turned out that wasn't correct.
Upvotes: 1
Views: 266
Reputation: 495
I suppose web3.eth.getCoinbase()
does not return a promise (so you are not awaiting anything here. You need to wrap the function call in a promise like this :
await new Promise((resolve, reject) => {
web3.eth.getCoinbase(function(err, account) {
if (err !== null) {
return reject(err)
}
App.account = account;
return resolve(account)
});
})
In this case, you don't actually need initAccount
to be an asynchronous function, you can refactor your function to be :
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)
});
})
}
Upvotes: 2
Reputation: 30092
From a style standpoint, you're best off not mixing callbacks and async/await in terms of sequential flow. To use callback style functions and weave them in with async/await, you can wrap them in promises to "hide" the promises away:
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
Upvotes: 1
Reputation: 1075527
I suspect web3.eth.getCoinbase
doesn't return a promise, since you're passing a callback to it. await
only awaits promises.
So you probably need to wrap that API in a promise, which means that initAccount
wouldn't need to be an async
function as this is one of the rare situations where you need 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);
}
});
});
}
Separately, if bindEvents
and render
do their work synchronously, you'd usually put them in the same then
handler:
return App.initAccount().then(() => {
App.bindEvents();
App.render();
});
Upvotes: 0
Reputation: 9964
getCoinbase
does not look like a function returning a promise. You should wrap it to behave as expected.
Either manually:
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);
});
});
Or using something like this
Upvotes: 0