Would it make any difference if I have:
async function test () {
const foo = await bar()
return Promise.all([promise1, promise2])
}
instead of:
async function test () {
const foo = await bar()
const [result1, result2] = await Promise.all([promise1, promise2])
// Given that I don't care about result1, result2 in this `test` function
return [result1, result2]
}
I get the same result if I do either. E.g. I can do this for either case:
test().then(([result1, result2]) => { ... })
but I am more curious about the underlying mechanism how they both behave the same.
In other words, how does async function handle it if inside the function I return a promise instead of a value?
I think you're effectively calling synchronous-like functions with await within the promise chain which, according to this answer:
You are perfectly free to call either synchronous functions within the
promise chain (from within .then() handlers) or asynchronous functions
that then return a new promise.
When you return something from a .then() handler, you can return
either a value (which becomes the resolved value of the parent
promise) or you can return another promise (which chains onto the
previous promise) or you can throw which works like returning a
rejected promise (the promise chain becomes rejected).
I would think the way async functions works in respect to the return value is it checks whether that value is wrapped in a Promise object, and if not, does it automatically. If you explicitly return a Promise, then the function does nothing with it. I tested this out by returning a new Promise inside an async function:
async function test(){
var duration = resolveAfter(500)
return new Promise((resolve, reject) =>{})
}
var neverresolved = test()
The result is neverresolved contains a Promise that's always in the pending state, as expected.
Both functions return a Promise.
const [result1, result2] = await Promise.all([promise1, promise2])
//HERE
return [result1, result2]
Where I wrote HERE you can access to result1 and result2 var that are the results of the promises.
await is an alternative to call then on Promise and its form is also more readable than
Promise.all([promise1, promise2]).then(function(results){
});
If you have multiple sequentially requests using await is a better choice
var response1= await promise1
var response2=await promise2
against
promise1.then(function(){
promise2.then(function(){
promise3.then(function(){
})
})
})
EDIT
In the first function the keyword async is useless, the function test will return a Promise
The second function will return a Promise where you see the keyword await. When the awaited promise will resolved the execution inside the function continue and you can access to result of the promise
EDIT 1
MaybeI understand what you mean, the async keyword encapsulate your return value into a promise that has as resolved value what you have returned
Related
I'm trying to understand how async/await works in conjunction together with promises.
Code
async function latestTime() {
const bl = await web3.eth.getBlock('latest');
console.log(bl.timestamp); // Returns a primitive
console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
return bl.timestamp;
}
const time = latestTime(); // Promise { <pending> }
Issue
As far as I understand, await should be blocking and in the code above it seemingly blocks returning an object bl with the primitive timestamp. Then, my function returns the primitive value, however the time variable is set to a pending promise instead of that primitive. What am I missing?
Async prefix is a kind of wrapper for Promises.
async function latestTime() {
const bl = await web3.eth.getBlock('latest');
console.log(bl.timestamp); // Returns a primitive
console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
return bl.timestamp;
}
Is the same as
function latestTime() {
return new Promise(function(resolve,success){
const bl = web3.eth.getBlock('latest');
bl.then(function(result){
console.log(result.timestamp); // Returns a primitive
console.log(typeof result.timestamp.then == 'function'); //Returns false - not a promise
resolve(result.timestamp)
})
}
An async function always returns a promise. That's how it reports the completion of its asynchronous work. If you're using it in another async function, you can use await to wait for its promise to settle, but in a non-async function (often at the top level or in an event handler), you have to use the promise directly, e.g.:
latestTime()
.then(time => {
console.log(time);
})
.catch(error => {
// Handle/report error
});
...though if you're doing this at the top level of a JavaScript module, all modern environments now support top-level await in modules:
const time = await latestTime();
(Note that if that promise is rejected, your module will fail to load. If your module can work meaningfully even if the promise fails, be sure to wrap that in try/catch to handle promise rejection.)
It might (or might not) throw some light on things to see, in explicit promise callback terms, how the JavaScript engine handles your async function under the covers:
function latestTime() {
return new Promise((resolve, reject) => {
web3.eth.getBlock('latest')
.then(bl => {
console.log(bl.timestamp);
console.log(typeof bl.timestamp.then == 'function');
resolve(bl.timestamp);
})
.catch(reject);
});
}
Some important notes on that:
The function you pass to new Promise (the promise executor function) gets called synchronously by new Promise.
Which is why the operation starts, web3.eth.getBlock is called synchronously to start the work.
Any error (etc.) thrown within the promise executor gets caught by new Promise and converted into a promise rejection.
Any error (etc.) thrown within a promise callback (like the one we're passing then) will get caught and converted into a rejection.
async function will return Promise anyway. Return value will be `Promise, so in your case it will be:
async function latestTime(): Promise<some primitive> {
const bl = await web3.eth.getBlock('latest');
return bl.timestamp;
}
So, further you can use it function like:
const time = await latestTime();
But for achieving general view about async/await feature it will be better to read documentation.
I'm trying to understand how async/await works in conjunction together with promises.
Code
async function latestTime() {
const bl = await web3.eth.getBlock('latest');
console.log(bl.timestamp); // Returns a primitive
console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
return bl.timestamp;
}
const time = latestTime(); // Promise { <pending> }
Issue
As far as I understand, await should be blocking and in the code above it seemingly blocks returning an object bl with the primitive timestamp. Then, my function returns the primitive value, however the time variable is set to a pending promise instead of that primitive. What am I missing?
Async prefix is a kind of wrapper for Promises.
async function latestTime() {
const bl = await web3.eth.getBlock('latest');
console.log(bl.timestamp); // Returns a primitive
console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
return bl.timestamp;
}
Is the same as
function latestTime() {
return new Promise(function(resolve,success){
const bl = web3.eth.getBlock('latest');
bl.then(function(result){
console.log(result.timestamp); // Returns a primitive
console.log(typeof result.timestamp.then == 'function'); //Returns false - not a promise
resolve(result.timestamp)
})
}
An async function always returns a promise. That's how it reports the completion of its asynchronous work. If you're using it in another async function, you can use await to wait for its promise to settle, but in a non-async function (often at the top level or in an event handler), you have to use the promise directly, e.g.:
latestTime()
.then(time => {
console.log(time);
})
.catch(error => {
// Handle/report error
});
...though if you're doing this at the top level of a JavaScript module, all modern environments now support top-level await in modules:
const time = await latestTime();
(Note that if that promise is rejected, your module will fail to load. If your module can work meaningfully even if the promise fails, be sure to wrap that in try/catch to handle promise rejection.)
It might (or might not) throw some light on things to see, in explicit promise callback terms, how the JavaScript engine handles your async function under the covers:
function latestTime() {
return new Promise((resolve, reject) => {
web3.eth.getBlock('latest')
.then(bl => {
console.log(bl.timestamp);
console.log(typeof bl.timestamp.then == 'function');
resolve(bl.timestamp);
})
.catch(reject);
});
}
Some important notes on that:
The function you pass to new Promise (the promise executor function) gets called synchronously by new Promise.
Which is why the operation starts, web3.eth.getBlock is called synchronously to start the work.
Any error (etc.) thrown within the promise executor gets caught by new Promise and converted into a promise rejection.
Any error (etc.) thrown within a promise callback (like the one we're passing then) will get caught and converted into a rejection.
async function will return Promise anyway. Return value will be `Promise, so in your case it will be:
async function latestTime(): Promise<some primitive> {
const bl = await web3.eth.getBlock('latest');
return bl.timestamp;
}
So, further you can use it function like:
const time = await latestTime();
But for achieving general view about async/await feature it will be better to read documentation.
I'm trying to understand how async/await works in conjunction together with promises.
Code
async function latestTime() {
const bl = await web3.eth.getBlock('latest');
console.log(bl.timestamp); // Returns a primitive
console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
return bl.timestamp;
}
const time = latestTime(); // Promise { <pending> }
Issue
As far as I understand, await should be blocking and in the code above it seemingly blocks returning an object bl with the primitive timestamp. Then, my function returns the primitive value, however the time variable is set to a pending promise instead of that primitive. What am I missing?
Async prefix is a kind of wrapper for Promises.
async function latestTime() {
const bl = await web3.eth.getBlock('latest');
console.log(bl.timestamp); // Returns a primitive
console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
return bl.timestamp;
}
Is the same as
function latestTime() {
return new Promise(function(resolve,success){
const bl = web3.eth.getBlock('latest');
bl.then(function(result){
console.log(result.timestamp); // Returns a primitive
console.log(typeof result.timestamp.then == 'function'); //Returns false - not a promise
resolve(result.timestamp)
})
}
An async function always returns a promise. That's how it reports the completion of its asynchronous work. If you're using it in another async function, you can use await to wait for its promise to settle, but in a non-async function (often at the top level or in an event handler), you have to use the promise directly, e.g.:
latestTime()
.then(time => {
console.log(time);
})
.catch(error => {
// Handle/report error
});
...though if you're doing this at the top level of a JavaScript module, all modern environments now support top-level await in modules:
const time = await latestTime();
(Note that if that promise is rejected, your module will fail to load. If your module can work meaningfully even if the promise fails, be sure to wrap that in try/catch to handle promise rejection.)
It might (or might not) throw some light on things to see, in explicit promise callback terms, how the JavaScript engine handles your async function under the covers:
function latestTime() {
return new Promise((resolve, reject) => {
web3.eth.getBlock('latest')
.then(bl => {
console.log(bl.timestamp);
console.log(typeof bl.timestamp.then == 'function');
resolve(bl.timestamp);
})
.catch(reject);
});
}
Some important notes on that:
The function you pass to new Promise (the promise executor function) gets called synchronously by new Promise.
Which is why the operation starts, web3.eth.getBlock is called synchronously to start the work.
Any error (etc.) thrown within the promise executor gets caught by new Promise and converted into a promise rejection.
Any error (etc.) thrown within a promise callback (like the one we're passing then) will get caught and converted into a rejection.
async function will return Promise anyway. Return value will be `Promise, so in your case it will be:
async function latestTime(): Promise<some primitive> {
const bl = await web3.eth.getBlock('latest');
return bl.timestamp;
}
So, further you can use it function like:
const time = await latestTime();
But for achieving general view about async/await feature it will be better to read documentation.
I'm trying to understand how async/await works in conjunction together with promises.
Code
async function latestTime() {
const bl = await web3.eth.getBlock('latest');
console.log(bl.timestamp); // Returns a primitive
console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
return bl.timestamp;
}
const time = latestTime(); // Promise { <pending> }
Issue
As far as I understand, await should be blocking and in the code above it seemingly blocks returning an object bl with the primitive timestamp. Then, my function returns the primitive value, however the time variable is set to a pending promise instead of that primitive. What am I missing?
Async prefix is a kind of wrapper for Promises.
async function latestTime() {
const bl = await web3.eth.getBlock('latest');
console.log(bl.timestamp); // Returns a primitive
console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
return bl.timestamp;
}
Is the same as
function latestTime() {
return new Promise(function(resolve,success){
const bl = web3.eth.getBlock('latest');
bl.then(function(result){
console.log(result.timestamp); // Returns a primitive
console.log(typeof result.timestamp.then == 'function'); //Returns false - not a promise
resolve(result.timestamp)
})
}
An async function always returns a promise. That's how it reports the completion of its asynchronous work. If you're using it in another async function, you can use await to wait for its promise to settle, but in a non-async function (often at the top level or in an event handler), you have to use the promise directly, e.g.:
latestTime()
.then(time => {
console.log(time);
})
.catch(error => {
// Handle/report error
});
...though if you're doing this at the top level of a JavaScript module, all modern environments now support top-level await in modules:
const time = await latestTime();
(Note that if that promise is rejected, your module will fail to load. If your module can work meaningfully even if the promise fails, be sure to wrap that in try/catch to handle promise rejection.)
It might (or might not) throw some light on things to see, in explicit promise callback terms, how the JavaScript engine handles your async function under the covers:
function latestTime() {
return new Promise((resolve, reject) => {
web3.eth.getBlock('latest')
.then(bl => {
console.log(bl.timestamp);
console.log(typeof bl.timestamp.then == 'function');
resolve(bl.timestamp);
})
.catch(reject);
});
}
Some important notes on that:
The function you pass to new Promise (the promise executor function) gets called synchronously by new Promise.
Which is why the operation starts, web3.eth.getBlock is called synchronously to start the work.
Any error (etc.) thrown within the promise executor gets caught by new Promise and converted into a promise rejection.
Any error (etc.) thrown within a promise callback (like the one we're passing then) will get caught and converted into a rejection.
async function will return Promise anyway. Return value will be `Promise, so in your case it will be:
async function latestTime(): Promise<some primitive> {
const bl = await web3.eth.getBlock('latest');
return bl.timestamp;
}
So, further you can use it function like:
const time = await latestTime();
But for achieving general view about async/await feature it will be better to read documentation.
I'm trying to understand how async/await works in conjunction together with promises.
Code
async function latestTime() {
const bl = await web3.eth.getBlock('latest');
console.log(bl.timestamp); // Returns a primitive
console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
return bl.timestamp;
}
const time = latestTime(); // Promise { <pending> }
Issue
As far as I understand, await should be blocking and in the code above it seemingly blocks returning an object bl with the primitive timestamp. Then, my function returns the primitive value, however the time variable is set to a pending promise instead of that primitive. What am I missing?
Async prefix is a kind of wrapper for Promises.
async function latestTime() {
const bl = await web3.eth.getBlock('latest');
console.log(bl.timestamp); // Returns a primitive
console.log(typeof bl.timestamp.then == 'function'); //Returns false - not a promise
return bl.timestamp;
}
Is the same as
function latestTime() {
return new Promise(function(resolve,success){
const bl = web3.eth.getBlock('latest');
bl.then(function(result){
console.log(result.timestamp); // Returns a primitive
console.log(typeof result.timestamp.then == 'function'); //Returns false - not a promise
resolve(result.timestamp)
})
}
An async function always returns a promise. That's how it reports the completion of its asynchronous work. If you're using it in another async function, you can use await to wait for its promise to settle, but in a non-async function (often at the top level or in an event handler), you have to use the promise directly, e.g.:
latestTime()
.then(time => {
console.log(time);
})
.catch(error => {
// Handle/report error
});
...though if you're doing this at the top level of a JavaScript module, all modern environments now support top-level await in modules:
const time = await latestTime();
(Note that if that promise is rejected, your module will fail to load. If your module can work meaningfully even if the promise fails, be sure to wrap that in try/catch to handle promise rejection.)
It might (or might not) throw some light on things to see, in explicit promise callback terms, how the JavaScript engine handles your async function under the covers:
function latestTime() {
return new Promise((resolve, reject) => {
web3.eth.getBlock('latest')
.then(bl => {
console.log(bl.timestamp);
console.log(typeof bl.timestamp.then == 'function');
resolve(bl.timestamp);
})
.catch(reject);
});
}
Some important notes on that:
The function you pass to new Promise (the promise executor function) gets called synchronously by new Promise.
Which is why the operation starts, web3.eth.getBlock is called synchronously to start the work.
Any error (etc.) thrown within the promise executor gets caught by new Promise and converted into a promise rejection.
Any error (etc.) thrown within a promise callback (like the one we're passing then) will get caught and converted into a rejection.
async function will return Promise anyway. Return value will be `Promise, so in your case it will be:
async function latestTime(): Promise<some primitive> {
const bl = await web3.eth.getBlock('latest');
return bl.timestamp;
}
So, further you can use it function like:
const time = await latestTime();
But for achieving general view about async/await feature it will be better to read documentation.