async await原理

async/await 的基础使用及原理简介 https://www.cnblogs.com/zhengyufeng/p/11106901.html

async/await是es7推出的一套关于异步的终极解决方案,为什么要说他是终极解决方案呢?因为他实在是太好用了,而且写起来还非常的简单。

一:async/await基础语法

// 定义一个异步函数(假设他是一个异步函数)getJSON(){return'JSON'}// 在需要使用上面异步函数的函数前面,加上async声明,声明这是一个异步函数asynctestAsync(){// 在异步函数前面加上await,函数执行就会等待用await声明的异步函数执行完毕之后,在往下执行awaitgetJSON()    ...剩下的代码}

以上就是async/await最基本的用法。

还需要注意的一点就是使用async/await的时候,是无法捕获错误的,这个时候就要用到我们es5里面一个被大家遗忘了的try/catch,来进行错误的捕获:

asynctestAsync() {try{awaitgetJSON()  }catch(err) {console.log(err)  }  ...剩下的代码}

注意:

1.async函数在声明形式上和普通函数没有区别,函数声明式,函数表达式,对象方法,class方法和箭头函数等都可以声明async函数。

2.任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。

3.async函数返回的 Promise 对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。

二:async/await

async

async这个单词大家应该都比较熟悉,他是英文单词‘异步’的简写,代表的意思也是异步。

asyncfunctiontestAsync(){return"hello async";}constresult = testAsync();console.log(result);

输出结果:

Promise{:"hello async"}

可以看出async函数,返回的是一个Promise对象

await

await是英文单词‘等待’的意思,代表的意思也是等待,那他等的到底是个什么东西呢?还是一个Promise。

三 async/await和Generator

Generator函数:generator(生成器)是ES6标准引入的新的数据类型。一个generator看上去像一个函数,但可以返回多次。下面面是一个Generator函数的简单写法。

function*Generator(){yield'11111111';yield'22222222'return'3333333';        }letaaa = Generator();

Generator函数和普通函数一样通过函数名+()去调用,但是调用完之后并不执行。它仅仅是创建了一个generator对象,还没有去执行它。想要运行Generator函数,需要通过遍历器对象的next方法。

leta = aaa.next()letb = aaa.next()letc = aaa.next()letd = aaa.next()    console.log(a,b,c,d) //  {value:"11111111",done:false}    {value:"22222222",done:false}      {value:"3333333",done:true}    {value: undefined,done:true}

想要Generator函数执行下一步,必须调用遍历器对象的next方法,使得指针移向下一个状态。也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式或return语句。由此可见,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行。也就是上面说的可以交出函数的执行权。

上面对Generator函数做了一个简单的介绍,接下来说一下async/await和Generator。

根据阮一峰老师的介绍,async函数就是Generator函数的语法糖。

图片:

代码上看起来,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await。

实际上async函数对Generator函数的改进,体现在一下四点:

1.async函数自带执行器,所以执行方式和普通函数的执行方式一样,通过函数名+()的方式执行。

2.async和await比起*和yield在语义上更清楚。

3.co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,但这时会自动转成立即 resolved 的 Promise 对象)。

4.async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。

进一步说,async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖。

四:async/await和Promise

上面说了async/await和Generator的关系,这里再说一下和Promise的关系,async/await其实是基于Promise的。async函数其实是把Promise包装了一下。

下面是一个async/await的写法:

getConstant() {return1}asyncgetAsyncConstant() {return1}asyncgetPromise() {returnnewPromise((resolved, rejected)=>{    resolved(1)  }); }asynctest() {leta =2letc =1awaitgetConstant();letd =3awaitgetPromise();letd =4awaitgetAsyncConstant();return2}

上面的代码其实真正的在解析执行的时候是这样的:

functiongetConstant(){return1;}functiongetAsyncConstant(){returnPromise.resolve().then(function(){return1;  });}functiongetPromise(){returnPromise.resolve().then(function(){returnnewPromise((resolved, rejected) =>{    resolved(1);  });  });}  test() {returnPromise.resolve().then(function(){leta =2;letc =1;returngetConstant();    }).then(function(){letd =3;returngetPromise();    }).then(function(){letd =4;returngetAsyncConstant();    }).then(function(){return2;    }); }

通过上面的代码可以看出async/await的本身还是基于Promise的。

因为await本身返回的也是一个Promise,它只是把await后面的代码放到了await返回的Promise的.then后面,以此来实现的。

做个练习:

functiongetJson(){returnnewPromise((reslove,reject) =>{        setTimeout(function(){console.log(2)          reslove(2)        },2000)      })    }asyncfunctiontestAsync(){awaitgetJson()console.log(3)    }    testAsync()

上面的代码是会先打印2还是3?

答案是2,3

看过上面的童鞋应该知道其实他的真实代码是这样的:

functiongetJson(){returnnewPromise((reslove,reject) =>{      setTimeout(function(){console.log(2)        reslove()      },2000)    })}functiontestAsync(){returnnewPromise((reslove,reject) =>{        getJson().then(function(res){console.log(3)        })    })}testAsync()

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容