异步处理promise 、Generator与 async await

前端开发中会遇到某些场景存在异步问题,比如从后端请求到数据以后才能继续往下执行某函数,最常见的写法是将函数调用写在请求数据的回调函数里,待请求函数执行完毕后再执行下面的函数,但是此方法有一弊端就是若业务逻辑太过复杂时,会一层层使用回调 ,使得代码可读性与维护性变得很差(回调地狱)。

promise:es6提供了原生的promise对象,promise对象代表了未来将要发生的事件,用来传递异步操作的消息

两个特点:

1、不受外界影响,代表一个异步操作,有三种状态:pending(初始状态非成功与失败状态),fulfilled(操作成功状态),rejected(失败状态)

2、一旦状态改变就不会再变:只有两种情况,从pending变为resolveed或者从pending变为rejected状态,只要发生就不再改变

优缺点:优点是避免了层层嵌套的回调函数, promise对象还提供了提供了统一的接口,使控制异步操作更加容易

缺点是无法取消Promise,一旦新建就必须完成,若不设置回调函数,promise内部返回的错误就不会反应到外部,当处于pending状态时,无法得知目前进行到了那个阶段

promise的创建:


已经实例化过的对象可以调用promise.then方法,传递resove方法和reject方法作为回调

promise.then(onFulfilled, onRejected);promise简化了错误处理的方法,我们也可以这样写:promise.then(onFulfilled).catch(onRejected)

链式操作:Promise.prototype.then返回的是一个新的Promise对象,因此可以采用链式写法


Promise链式操作可以使异步函数按特定顺序执行,一定程度上避免了回调地狱,代码可读性与可维护行提高

Promise.proptype.catch方法捕捉错误:

Promise.prototype.catch 方法是 Promise.prototype.then(null, rejection) 的别名,用于指定发生错误时的回调函数。

Promise 对象的错误具有"冒泡"性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个 catch 语句捕获。

Promise.all方法:Promise.all 方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

var p = Promise.all([p1,p2,p3]);

上面代码中,Promise.all 方法接受一个数组作为参数,p1、p2、p3 都是 Promise 对象的实例。(Promise.all 方法的参数不一定是数组,但是必须具有 iterator 接口,且返回的每个成员都是 Promise 实例。)

p 的状态由 p1、p2、p3 决定,分成两种情况。

(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

Promise.race 方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

var p = Promise.race([p1,p2,p3]);

上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的返回值。

Generator:ES6 新引入了 Generator 函数,可以通过 yield 关键字,把函数的执行流挂起,为改变执行流程提供了可能,从而为异步编程提供解决方案。

Generator 有两个区分于普通函数的部分:

一是在 function 后面,函数名之前有个 * ;

函数内部有 yield 表达式。

其中 * 用来表示函数为 Generator 函数,yield 用来定义函数内部的状态。

执行机制

调用 Generator 函数和调用普通函数一样,在函数名后面加上()即可,但是 Generator 函数不会像普通函数一样立即执行,而是返回一个指向内部状态对象的指针,所以要调用遍历器对象Iterator 的 next 方法,指针就会从函数头部或者上一次停下来的地方开始执行。

除了使用 next ,还可以使用 for... of 循环遍历 Generator 函数生产的 Iterator 对象。
return 方法返回给定值,并结束遍历 Generator 函数。return 方法提供参数时,返回该参数;不提供参数时,返回 undefined 。

throw 方法:


throw 方法可以再在Generator 函数体外面抛出异常,在函数体内部捕获。遍历器对象抛出了两个错误,第一个被 Generator 函数内部捕获,第二个因为函数体内部的catch 函数已经执行过了,不会再捕获这个错误,所以这个错误就抛出 Generator 函数体,被函数体外的 catch 捕获。


yield* 表达式表示 yield 返回一个遍历器对象,用于在 Generator 函数内部,调用另一个 Generator 函数。使用场景实现 Iterator为不具备 Iterator 接口的对象提供遍历方法。


async方法

async 是 ES7 才有的与异步操作有关的关键字,和 Promise , Generator 有很大关联的。

async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数

async 函数中可能会有 await 表达式,async 函数执行时,如果遇到 await 就会先暂停执行 ,等到触发的异步操作完成后,恢复 async 函数的执行并返回解析值。

注意await的函数返回的是一个Promise对象,所以必须要将异步函数写到Promise对象里,await 操作符用于等待一个 Promise 对象, 它只能在异步函数 async function 内部使用。

返回值:返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。

如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果。

await针对所跟不同表达式的处理方式:Promise 对象:await 会暂停执行,等待 Promise 对象 resolve,然后恢复 async 函数的执行并返回解析值。非 Promise 对象:直接返回对应的值。

await 命令后面是一个 Promise 对象,它也可以跟其他值,如字符串,布尔值,数值以及普通函数。

本文部分内容参考自菜鸟教程ES6教程

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

推荐阅读更多精彩内容