简体   繁体   中英

Javascript Promise with Await Explanation

I would just like to understand how promises and await work together. Look at the following code:

console.log("One: Started");
setTimeout(function(){console.log("One: Completed")}, 1000);
console.log("Two: Started");
setTimeout(function(){console.log("Two: Completed")}, 2000);
console.log("Three: Started");
setTimeout(function(){console.log("Three: Completed")}, 3000);

So this of course logs:

One: Started
Two: Started
Three: Started
One: Completed
Two: Completed
Three: Completed

I would like to have the one complete before the next one starts. I wrote this with my understanding of promises and await but this is not working. Would someone please try and edit this code to get it working. And please and an explanation as I am trying to understand promises and await

async function LogAll() {
    console.log("One: Started");
    await function() {
        return new Promise((resolve, reject) => {
            setTimeout(function(){
                console.log("One: Completed");
                resolve();
            }, 1000);
        });
    }
    console.log("Two: Started");
    await function() {
        return new Promise((resolve, reject) => {
            setTimeout(function(){
                console.log("Two: Completed");
                resolve();
            }, 2000);
        });
    }
    console.log("Three: Started");
    await function() {
        return new Promise((resolve, reject) => {
            setTimeout(function(){
                console.log("Three: Completed");
                resolve();
            }, 3000);
        });
    }
}

LogAll();

You need to await promises , not functions alone. When you await function ... (without calling it), the function is evaluated as an expression and then discarded. Just call the functions:

 async function LogAll() { console.log("One: Started"); await (function() { return new Promise((resolve, reject) => { setTimeout(function() { console.log("One: Completed"); resolve(); }, 1000); }); })(); console.log("Two: Started"); await (function() { return new Promise((resolve, reject) => { setTimeout(function() { console.log("Two: Completed"); resolve(); }, 2000); }); })(); console.log("Three: Started"); await (function() { return new Promise((resolve, reject) => { setTimeout(function() { console.log("Three: Completed"); resolve(); }, 3000); }); })(); } LogAll(); 

Or, for this example, don't use functions at all - just await the promises directly:

 async function LogAll() { console.log("One: Started"); await new Promise((resolve, reject) => { setTimeout(function() { console.log("One: Completed"); resolve(); }, 1000); }); console.log("Two: Started"); await new Promise((resolve, reject) => { setTimeout(function() { console.log("Two: Completed"); resolve(); }, 2000); }); console.log("Three: Started"); await new Promise((resolve, reject) => { setTimeout(function() { console.log("Three: Completed"); resolve(); }, 3000); }); } LogAll(); 

The async function declaration defines an asynchronous function , which returns an AsyncFunction object.

An async function can contain an await expression that pauses the execution of the async function and waits for the passed Promise's resolution, and then resumes the async function's execution and returns the resolved value.

 function resolveAfter2Seconds() { return new Promise(resolve => { setTimeout(() => { resolve('calling'); }, 2000); }); } async function asyncCall() { var result = await resolveAfter2Seconds(); console.log(result); // expected output: "resolved" console.log('called'); } asyncCall(); 

For More refer Async Await

What is an async Function:

It is a function which returns a AsyncFunction Object, similar to Promises. If it throws an error, the object rejects, otherwise when it returns a value, it resolves.

Async Functions are newer and before they existed there were different ways to write asynchronous code: Promises (part of rxjs), Observables ("infinite Promises"), callbacks used with timing events.

What is the await keyword:

In Javascript the await keyword can only be used inside an async Function with the following syntax:

[returnValue] = await expression;

Where the expression can be a Promise or any other value returned by asynchronous code.

await tells the code to stop and wait for that value.

Without that, the returnValue in the above expression would be immediately given a value (undefined most probably) and the code will continue without blocking. After some unknown time and unknown point in the code, the function will finally return and returnValue will finally receive the correct value. But maybe the code went forward and wrongly assumed you already had a defined and updated value, possibly failing.

Try to run the snippets without async await. They are counter examples to show the corresponding synchronous code:

EXAMPLE 1: all Promises are started immediately

 function LogAll() { console.log("One: Started"); new Promise((resolve, reject) => { setTimeout(function() { console.log("One: Completed"); resolve(); }, 1000); }); console.log("Two: Started"); new Promise((resolve, reject) => { setTimeout(function() { console.log("Two: Completed"); resolve(); }, 2000); }); console.log("Three: Started"); new Promise((resolve, reject) => { setTimeout(function() { console.log("Three: Completed"); resolve(); }, 3000); }); } LogAll(); 

EXAMPLE 2: No promises at all (identical results to example 1)

 function LogAll() { console.log("One: Started"); setTimeout(function() { console.log("One: Completed"); }, 1000); console.log("Two: Started"); setTimeout(function() { console.log("Two: Completed"); }, 2000); console.log("Three: Started"); setTimeout(function() { console.log("Three: Completed"); }, 3000); } LogAll(); 

In Example 2 please note that setTimeout is a timing event, an older feature of Javascript, so it does not really need a wrapper Promise, except the Promise allows you to throw errors and reject.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM