What does async do

The async function returns a Promise object; If you return an immediate quantity in a function, async encapsulates the immediate quantity into a Promise object via promise.resolve (). Promise.resolve(x) can be thought of as a shorthand for new Promise(resolve => resolve(x)) and can be used to quickly encapsulate literal objects or other objects as Promise instances. So we can make chain calls using then after calling async modified functions

// Example 1:
async function testAsync() {
    return "hello async";
}

const result = testAsync();
console.log(result);	// result is a promise. Promise {'hello async'}


testAsync().then(v= > {
    console.log(v);		// Outputs Hello async
});
Copy the code

If async does not return a value, it is easy to imagine that it will return promise.resolve (undefined).

async function testAsync(){
	return;
}
let res = testAsync();
console.dir(res)	// Promise { undefined }
Copy the code

Think of Promise as a feature-no wait, so an async function executed without await will execute immediately, return a Promise object, and never block subsequent statements. This is no different than a normal function that returns a Promise object; So the next key point is the await keyword

What is await waiting for

Await can only be used inside async functions.

Await expression suspends execution of the current async function until the Promise processing completes. If the Promise is fulfilled normally, the resolve parameter of its callback will be the value of the await expression and the async function will continue to be executed.

Await syntax: Return value = await expression

Await return value:

If a Promise handles an exception (Rejected), the await expression throws the Promise’s exception reason.

1. awaitIf it's a promise, thenawaitWaits for the promise to complete, taking the promise's resolve argument asawaitThe return value of. If the expression promise is called chained, that is, if there are more than one THEN, then awaite takes the resolve argument in the final THEN orreturnValue of, asawaitThe return value of2.If you pass it toawaitIs not a value ofPromise.awaitReturn the value directly3.PromiseException Handling (Rejected),awaitThe expression will takePromiseThe exception cause is thrown. (equivalent to directthrowWrong reason, needcatchYou can get it.Copy the code
// Example 1:
function resolveAfter2Seconds(x) {
  return new Promise(resolve= > {
    setTimeout(() = > {
      resolve(x);
    }, 2000);
  });
}

async function f1() {
  var x = await resolveAfter2Seconds(10);
  console.log(x); / / 10
}
f1();

// Example 2:
async function f2() {
  var y = await 20;
  console.log(y); / / 20
}
f2();


// Example 3:
function resolveAfter2Seconds (x) {
  return new Promise(resolve= > {
    resolve(x)
  }).then(res= > { return res + 30 });
}

async function f1 () {
  var x = await resolveAfter2Seconds(10);
  console.log(x);	/ / 40
}
let r = f1();
console.log(11111, r);	/ / promise object


// Example 4:2222: x does not print
function resolveAfter2Seconds (x) {
  return new Promise((resolve, reject) = > {
    reject(x)
  })
}
async function f1 () {
  var x
  try {
    x = await resolveAfter2Seconds(10);
  } catch (e) {
    console.log('66', e);	/ / 66 10
  }
  console.dir(2222, x);	/ / 2222
}
let r = f1();
console.log(11111, r);	// 11111 promise


/ / example 5:
function resolveAfter2Seconds (x) {
  return new Promise((resolve, reject) = > {
    resolve(x)
  }).then(arg= > {
    return new Promise((resolve, reject) = > {
      return resolve(100)})})}async function f1 () {
  var x = await resolveAfter2Seconds(10);
  console.log(1, x);	/ / 1, 100
}
let r = f1();
console.log(r);		// promise
Copy the code

Await execution order problem

Summary: The execution sequence is as follows: execute the code before await command, stop executing the code after await in async when encountering await, execute the code outside of async function, and then execute the line where await command inside async function is located and the code after await command is executed

// An example of the execution order:
console.log('aa')				// Step 1 prints aa
async function test(){
	console.log('bb')			// Step 2 prints bb
    const res = await 222
    console.log(res)			// Step 4 prints 222
    console.log('dd')			// Step 5 outputs dd
    return res
}
test().then( res= > console.log(res))	// Step 6 prints 222
setTimeout(() = > {
	console.log('ff')			// Step 7 prints ff
}, 5000)
console.log('cc')				// Step 3 prints cc


Copy the code
  • Example 1 ConclusionSince await mainly waits for the value of resolve of the promise as the return value of await itself,
// Example 1:
async function getStockPriceByName () {
    console.log("aa")

    const stockPrice = await new Promise((resolved, rejected) = > {
        setTimeout(() = > {
            console.log("time...")},5000);
        resolved(111);
    });
    console.log(stockPrice);
    console.log("bb")
    return stockPrice;
}

getStockPriceByName().then(function (result) {
    console.log(result);
});

/ / output:
aa
111
bb
111
// The time interval is 5 seconds.
time...

// Conclusion: await mainly the return value of the promise resolved
Copy the code
  • Example 2 ConclusionResolve cannot return parameters, await cannot finish, await cannot execute code after await
// Example 2:
async function getStockPriceByName () {
    console.log("aa")

    const stockPrice = await new Promise((resolved, rejected) = > {
        setTimeout(() = > {
            console.log("time...")
            resolved(111);
        }, 5000);
    });
    console.log(stockPrice);
    console.log("bb")
    return stockPrice;
}

getStockPriceByName().then(function (result) {
    console.log(result);
});


/ / output:
aa
// first print aa, then print the following 4 items after 5 seconds interval here
time...
111
bb
111

// Conclusion: await mainly the return value of the promise resolved
Copy the code
  • Example 3 Conclusion:
// Example 3:
async function getStockPriceByName () {
    console.log("aa")

    const stockPrice = await new Promise((resolved, rejected) = > {
        setTimeout(() = > {
            console.log("time...")
            resolved(111);
        }, 5000);
    });
    console.log(stockPrice);
    console.log("bb")
    return stockPrice;
}

getStockPriceByName().then(function (result) {
    console.log(result);
});
console.log('cc');

/ / output:
aa
cc
// The interval is 5 seconds
time...
111
bb
111

// conclusion: await blocks only the code inside async after await; The code outside the async function executes normally.
Copy the code

Reference: juejin.cn/post/684490…

  • Example 4 Conclusion: Remember that await is followed by an asynchronous operation, even the synchronous code of the previous Promise; Again, the default is asynchronous and none of the operations are performed.
// Example 4:
async function getStockPriceByName () {
    console.log("aa")

    const stockPrice = await new Promise((resolved, rejected) = > {
        setTimeout(() = > {
            console.log("time...")},5000);
        resolved(111);
    });
    console.log(stockPrice);
    console.log("bb")
    return stockPrice;
}

getStockPriceByName().then(function (result) {
    console.log(result);
});
console.log('cc');

/ / output:
aa
cc
111
bb
111
// The interval is 5 seconds
time...
Copy the code
  • Example 5 Conclusion: Stop the execution of async function after encountering await command inside async function, which is equivalent to the asynchronous operation encountered. In this case, the synchronous code outside async function shall be executed first, and the code after await command inside async function shall be executed again after the execution is finished
// Example 5:
async function getStockPriceByName () {
    console.log("aa")

    const stockPrice = await 222
    console.log(stockPrice);
    console.log("bb")
    return stockPrice;
}

getStockPriceByName().then(function (result) {
    console.log(result);
});
console.log('cc');

/ / output:
aa
cc
222
bb
222
Copy the code
  • Example 6 ConclusionSince await is actually an asynchronous processing of promise, it is executed before the macro task
// Example 6:
async function getStockPriceByName () {
    console.log("aa")

    const stockPrice = await 222
    console.log(stockPrice);
    console.log("bb")
    return stockPrice;
}

getStockPriceByName().then(function (result) {
    console.log(result);
});

setTimeout(() = > {
    console.log("ff");
}, 5000)
console.log('cc');

/ / output:
aa
cc
222
bb
222
// The interval is 5 seconds
ff
Copy the code

Error handling

If the Promise object following the await command becomes reject, the reject argument is received by the catch callback.

// Example 1: Reject reject, await return is the same
async function f() {
  await Promise.reject('Wrong');
}

f()
.then(v= > console.log(v))
.catch(e= > console.log(e))

/ / output:Make a mistakeCopy the code

Any Promise object after an await statement becomes reject, and the entire async function breaks

// Example 2:
async function f() {
  await Promise.reject('Wrong');
  await Promise.resolve('hello world'); 		// Will not execute; The state of the first await statement becomes reject
}
Copy the code

The way to prevent errors is to put it in a try… Inside the catch block

// Example 3:
async function main() {
  try {
    const val1 = await firstStep();
    const val2 = await secondStep(val1);
    const val3 = await thirdStep(val1, val2);

    console.log('Final: ', val3);
  }
  catch (err) {
    console.error(err); }}Copy the code

Batch concurrent execution

Asynchronous operations following multiple await commands, if there is no secondary relationship, it is best to let them fire simultaneously. Multiple requests are executed concurrently, using the promise.all method

/ / sample:

let foo = await getFoo();
let bar = await getBar();
// Parallel writing:
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
Copy the code

Usage scenarios of Async

Example 1 uses a promise to request the backend interface, and we have to get the data in then to process it; That is, data initialization depends on the result returned by the Promise request; In layman’s terms, when what we need to do depends on the result of an operation, we can write “await” the dependent operation, and it is ok.

You can compare example 1 and Example 2 to experience it

// Example 1:
getLessonList() {
  axios.get('/xxx', {
    params: {
      courseId: yyy
    }
  }).then(res= > {
    if (res && res.status && res.data) {
      this.lessonLists = res.data
      this.lessonLists.forEach(item= > {
        this.$set(item, 'xxx'.false)})this.$nextTick(() = > {
        this.initScroll()
      })
    }
  }).catch(error= > {
    console.log('getLessonListError', error)
  })
}

// Example 2:
async getCourseTask(item, courseId, lessonId) {
  try {
    let loadingInstance = this.$loading()
    let res = await axios.get('/xxx', {
      params: {
        xxx: true,}})this.$loading.stop(loadingInstance)
    if (res && res.status && res.data) {
      item.rankUrl = res.data.rankUrl
    }
  } catch (error) {
    console.log('getCourseTaskError', error)
  }
}

Copy the code