Disposable let you know async / await, to solve the callback hell

What is async?

Welcome Message Discussion

asyncFunction is Generatorsyntactic sugar function. Use the keyword asyncis represented internally using a function awaitto represent asynchronous. Compared to Generator, asyncimproved function is that the following four points:

  • Built-in actuator . GeneratorExecution of the function must rely on actuators and asyncfunction comes with actuators, calls the same way as with an ordinary function call

  • Better semantics . asyncAnd awaitcompared to *and yieldmore semantic

  • Broader applicability . coModule convention, yieldcommand or function behind only Thunk Promise objects. And asyncfunction awaitafter the command, or it may be a value Promise primitive type (Number, string, boolean, but this time is equivalent to the synchronous operation)

  • The return value is a Promise . asyncPromise function return value is an object, the object returns Iterator convenient than Generator function may be used directly then()method invocation

Summary References from here: understanding async / await

asyncES7 is a new feature, show the current function is asynchronous function, does not block the thread leading to subsequent code to stop running.

how to use

After affirms can be called up

async function asyncFn() {
  return 'hello world';
}
asyncFn();

This indicates that this is an asynchronous function that returned results

    1 

It returns an promiseobject state resolved, a parameter returnvalue. Look at the following function that

async function asyncFn() {
    return '我后执行'
}
asyncFn().then(result => {
    console.log(result);
})
console.log('我先执行');

 

1

The results of the above is to print out '我先执行', although it is above the asyncFn()first execution, but has been defined asynchronous functions, and will not affect the implementation of the follow-up function.

 

Now understand the asyncbasic usage, what is characteristic of it?

asyncInternal function defined by default return an promiseobject, if the internal throws an exception or returns reject, will cause the function of promisethe state as a failure reject.

 

 

 

async function e() {    
    throw new Error('has Error');
}
e().then(success => console.log('成功', success))   
   .catch(error => console.log('失败', error));

 

1

We see that throws an internal function 异常return reject, asyncfunction after receiving, enter judgment fails catch, the error returned by the print out.

 

 

 

async function throwStatus() {    
    return '可以返回所有类型的值'
}
throwStatus().then(success => console.log('成功', success))             
             .catch(error => console.log('失败', error));

 

 

 

 

//打印结果

成功 可以返回所有类型的值

 

asyncReceives the value returned by the function, is not found 异常or rejectis judged successful, there may be returnvalues of the various types of data, false, NaN, undefined... In short, allresolve

However, the following results will return asyncfunction determining failurereject

  1. Directly and internal containing undeclared variable or function.
  2. Internal throw an error throw new Erroror return rejectstatusreturn Promise.reject('执行失败')
  3. Function method execution error (: Object using the push ()), and so on ...

Another point in asyncwhere you want the results to be returnreturned, otherwise either executed rejector resolvedvalues are undefinerecommended to use the arrow functions.

The remaining results are returned determination resolvedexecuted successfully.

 

 

 

//正确reject方法。必须将reject状态return出去。
async function PromiseError() {    
   return Promise.reject('has Promise Error');
}

//这是错误的做法,并且判定resolve,返回值为undefined,并且Uncaught报错
async function PromiseError() {
  Promise.reject('这是错误的做法');
}

PromiseError().then(success => console.log('成功', success))              
              .catch(error => console.log('失败', error));

 

 

1

 

We see the second line of more than a Promisetarget print, do not care, this is Chromethe default behavior of the console, we usually assignment is the same effect in the console. If the last 执行语句or 表达式no returnreturn value, by default undefined, a little experiment.

 

 

 

var a = 1;
//undefined
------------------------------------------------------------
console.log(a);
//1
//undefined
------------------------------------------------------------
function a(){ console.log(1) }
a();
//1
//undefined
------------------------------------------------------------
function b(){ return console.log(1) }
b();
//1
//undefined
------------------------------------------------------------
function c(){ return 1}
c();
//1
------------------------------------------------------------
async function d(){
    '这个值接收不到'
}
d().then(success => console.log('成功',success));
//成功  undefined
//Promise { <resolved>: undefined }
-----------------------------------------------------------
async function e(){
    return '接收到了'
}
e().then(success => console.log('成功',success));
//成功  接收到了
//Promise { <resolved>: undefined }

 

The last line Promise { <resolved> : undefined }is because the return is console.logexecuting a statement, there is no return value.

 

 

 

d().then(success => console.log('成功',success)}
等同于
d().then(function(success){ 
            return console.log('成功',success);
        });

 

Understanding over async, Laijiangjiang await.

What await that?

awaitMeaning async wait (asynchronous wait). This keyword can only be used asyncusing a defined function inside. Any asyncfunction will return the default promise, and this promisevalue will resolve all is the return value of the function, and the asyncfunction must wait until all internal awaitcommand Promiseobjects executed, the state change will occur.

Figuratively, await students, async school bus, Qi, who must then drive.

That is, all have to wait awaitafter the function is finished, will tell promiseme the success or failure of execution thenorcatch

 

 

 

async function awaitReturn() {     
    return await 1
};
awaitReturn().then(success => console.log('成功', success))
             .catch(error => console.log('失败',error))

 

1

In this function, there is a awaitfunction, async will wait until await 1 this step will return to perform over promisethe state, no doubt, is determined resolved.

很多人以为await会一直等待之后的表达式执行完之后才会继续执行后面的代码,实际上await是一个让出线程的标志await后面的函数会先执行一遍,然后就会跳出整个async函数来执行后面js栈的代码。等本轮事件循环执行完了之后又会跳回到async函数中等待await后面表达式的返回值,如果返回值为非promise则继续执行async函数后面的代码,否则将返回的promise放入Promise队列(Promise的Job Queue)

来看个简单点的例子

 

 

 

const timeoutFn = function(timeout){ 
	return new Promise(function(resolve){
		return setTimeout(resolve, timeout);
               });
}

async function fn(){
    await timeoutFn(1000);
    await timeoutFn(2000);
    return '完成';
}

fn().then(success => console.log(success));

 

这里本可以用箭头函数写方便点,但是为了便于阅读本质,还是换成了ES5写法,上面执行函数内所有的await函数才会返回状态,结果是执行完毕3秒后才会弹出'完成'。

正常情况下,await 命令后面跟着的是 Promise ,如果不是的话,也会被转换成一个 立即 resolve 的 Promise。

也可以这么写

 

 

 

function timeout(time){
    return new Promise(function(resolve){
        return setTimeout(function(){ 
                    return resolve(time + 200)
               },time);
    })
}

function first(time){
    console.log('第一次延迟了' + time );
    return timeout(time);
}
function second(time){
    console.log('第二次延迟了' + time );
    return timeout(time);
}
function third(time){
    console.log('第三次延迟了' + time );
    return timeout(time);
}

function start(){
    console.log('START');
    const time1 = 500;
    first(time1).then(time2 => second(time2) )
                .then(time3 => third(time3)  )
                .then(res => {
                              console.log('最后一次延迟' + res );
                              console.timeEnd('END');
                             })
};
start();

这样用then链式回调的方式执行resolve

 

 

 

//打印结果

START
第一次延迟了500
第二次延迟了700
第三次延迟了900
最后一次延迟1100
END

 

用async/await呢?

 

 

 

async function start() {
    console.log('START');
    const time1 = 500;
    const time2 = await first(time1);
    const time3 = await second(time2);
    const res = await third(time3);
    console.log(`最后一次延迟${res}`);
    console.log('END');
}
start();

达到了相同的效果。但是这样遇到一个问题,如果await执行遇到报错呢

 

 

 

async function start() {
    console.log('START');
    const time1 = 500;
    const time2 = await first(time1);
    const time3 = await Promise.reject(time2);
    const res = await third(time3);
    console.log(`最后一次延迟${res}`);
    console.log('END');
}
start();

 

1

返回reject后,后面的代码都没有执行了,以此迁出一个例子:

 

 

 

let last;
async function throwError() {  
    await Promise.reject('error');    
    last = await '没有执行'; 
}
throwError().then(success => console.log('成功', last))
            .catch(error => console.log('失败',last))

 

1

 

其实

async函数不难,难在错处理上。

 

上面函数,执行的到await排除一个错误后,就停止往下执行,导致last没有赋值报错。

async里如果有多个await函数的时候,如果其中任一一个抛出异常或者报错了,都会导致函数停止执行,直接reject;

怎么处理呢,可以用try/catch,遇到函数的时候,可以将错误抛出,并且继续往下执行。

 

 

 

let last;
async function throwError() {  
    try{  
       await Promise.reject('error');    
       last = await '没有执行'; 
    }catch(error){
        console.log('has Error stop');
    }
}
throwError().then(success => console.log('成功', last))
            .catch(error => console.log('失败',last))

1

这样的话,就可以继续往下执行了。

 

 

来个练习下

 

 

 

 

function testSometing() {
    console.log("testSomething");
    return "return testSomething";
}

async function testAsync() {
    console.log("testAsync");
    return Promise.resolve("hello async");
}

async function test() {
    console.log("test start...");

    const testFn1 = await testSometing();
    console.log(testFn1);

    const testFn2 = await testAsync();
    console.log(testFn2);

    console.log('test end...');
}

test();

var promiseFn = new Promise((resolve)=> { 
                    console.log("promise START...");
                    resolve("promise RESOLVE");
                });
promiseFn.then((val)=> console.log(val));

console.log("===END===")

 

执行结果

1

 

我们一步步来解析

首先test()打印出test start...

然后 testFn1 = await testSomething(); 的时候,会先执行testSometing()这个函数打印出“testSometing”的字符串。

之后因为await会让出线程就会去执行后面的。testAsync()执行完毕返回resolve,触发promiseFn打印出“promise START...”。

接下来会把返回的Promiseresolve("promise RESOLVE")放入Promise队列(Promise的Job Queue),继续执行打印“===END===”。

等本轮事件循环执行结束后,又会跳回到async函数中(test()函数),等待之前await 后面表达式的返回值,因为testSometing() 不是async函数,所以返回的是一个字符串“returntestSometing”。

test()函数继续执行,执行到testFn2(),再次跳出test()函数,打印出“testAsync”,此时事件循环就到了Promise的队列,执行promiseFn.then((val)=> console.log(val));打印出“promise RESOLVE”。

之后和前面一样 又跳回到test函数继续执行console.log(testFn2)的返回值,打印出“hello async”。

最后打印“test end...”。

加点料,让testSomething()变成async

 

 

 

async function testSometing() {
    console.log("testSomething");
    return "return testSomething";
}

async function testAsync() {
    console.log("testAsync");
    return Promise.resolve("hello async");
}

async function test() {
    console.log("test start...");

    const testFn1 = await testSometing();
    console.log(testFn1);

    const testFn2 = await testAsync();
    console.log(testFn2);

    console.log('test end...');
}

test();

var promiseFn = new Promise((resolve)=> { 
                    console.log("promise START...");
                    resolve("promise RESOLVE");
                });
promiseFn.then((val)=> console.log(val));

console.log("===END===")

 

执行结果

1

And found a comparative example promiseFn.then((val)=> console.log(val));prior to console.log(testFn1);execution, the reason is because there testSomething()is already a asyncfunction that returns an Promiseobject that you want to wait for it resolve, so the current Promise push queue, it will continue to bounce test()function executing subsequent code. After the task began to execute Promise queue, so do an promise.then((val)=> console.log(val));Because this object is first pushed into the queue Promise.

More and more people are studying is said to be async / await the ultimate asynchronous programming solutions, but most people on this method is not very understanding how internal execution, execution order js compiled after await, hope you have help

  1. It is a new way to write asynchronous code. Before the program is asynchronous code callback and promise.
  2. It is based on the promise, and the promise is the same as non-blocking.
  3. async / await allow asynchronous code look, behave more like synchronous code. This is where its power.

References: understanding of JavaScript async / await


Author: paranoidゝ
link: https: //juejin.im/post/5b1ffff96fb9a01e345ba704
Source: Nuggets
copyright reserved by the authors. Commercial reprint please contact the author authorized, non-commercial reprint please indicate the source.

Reproduced in: https: //my.oschina.net/u/2436852/blog/1833275

Guess you like

Origin blog.csdn.net/weixin_34205076/article/details/92285528