关于Promise

概述:

Promise是一个构造函数,JS原生提供Promise对象。

Promise 对象用于表示一个异步操作的最终状态(完成或失败),以及该异步操作的结果值

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。


特点:

不同于老式的传入回调,在应用 Promise 时,将会有以下特点:

1.Promise会放到微队列中,因为他是异步执行,会插入到本轮事件循环的末尾,所以会晚于同步代码执行。

2.通过 .then()形式添加的回调函数都会被调用,即便是在异步操作完成之后才被添加的函数。

3.通过多次调用 .then(),可以添加多个回调函数,它们会按照插入顺序并且独立运行。

因此,Promise 最直接的好处就是链式调用


状态:

pending: 初始状态,既不是成功,也不是失败状态。

fulfilled: 意味着操作成功完成。

rejected: 意味着操作失败。


语法:

promise语法

Promise构造函数接受一个函数作为参数,先把这个函数叫做executor

executor是带有 resolve 和 reject 两个参数的函数 。Promise构造函数执行时立即调用executor 函数,resolve 和 reject 两个函数作为参数传递给executor(executor 函数在Promise构造函数返回实例对象前被调用)。resolve 和 reject 函数被调用时,分别将promise的状态改为fulfilled(完成)或rejected(失败)。executor 内部通常会执行一些异步操作,一旦异步操作执行完毕(可能成功/失败),要么调用resolve函数来将promise状态改成fulfilled,要么调用reject 函数将promise的状态改为rejected。如果在executor函数中抛出一个错误,那么该promise 状态为rejected。executor函数的返回值被忽略。

实例方法:

Promise.prototype.then(fun1(x),fun2(x))

该方法接受两个函数作为参数,promise的状态为成功时调用第一个参数,失败时调用第二个参数。也就是当resolve函数被成功调用时,触发then的第一个参数,当reject函数被调用时,触发then的第二个参数。

每个回调也都接受一个参数,分别为resolve和reject函数被调用时传入的参数。

then方法返回一个新的Promise对象,注意,是新的!


栗子:

当我传入1时,resolve执行(只要它执行了就代表成功了),看下控制台输出:

cosole.log

逻辑分析:执行promise ---> resolve函数执行 ---> then的第一个回调执行 ---> 返回一个新的promise对象 ---> then的第一个回调执行

看下例是如何失败的:

promise

当我传入9999时,reject函数被调用(它被调用就代表失败了),看控制台输出:

console.log

逻辑分析:执行promise ---> reject函数执行 ---> then的第二个回调执行 ---> 返回一个新的promise对象 ---> then的第一个回调执行


划重点:

promise明明失败了,为什么第二个then的第一个回调执行而不是第二个呢?因为then返回的是一个新的promise对象,和被传入9999执行的函数返回的不是同一个promise。此时也就是说新的promise的状态为成功,但如果第一个then的某个回调执行后发生错误,第二个then的第二个回调就会调用了,因为这是新的promise失败了。

对于新人纠结的问题(就是本人):这tm成功失败不就是if else控制的吗?

见下例:

promise

我擦?我干你大爷是什么鬼?见控制台输出:

console.log

逻辑分析:执行promise ---> 报错了!!! 默认调用reject函数,参数为抛出的错误对象 --->  then的第二个回调执行 ---> 返回一个新的promise对象 ---> then的第一个回调执行

结论:发生错误会自动调用reject,传入的参数是错误对象


Promise.prototype.catch(fun(x))

该方法接受一个函数作为参数,在失败时调用,也就是当reject函数被调用时触发该方法。也就是说它也能接收promise的失败状态,并执行回调函数,回调的参数为reject函数被调用时的传入的参数。见下例:

catch
console.log

如果promise抛出错误,比如上面那个‘我是你大爷’,也会执行catch

还有,如果then的回调发生错误,catch同样执行。

PS:catch后面接的then,回调函数内的console.log输出的内容我手误了,你可以看成我接收到catch回调传给我的参数是......


关于承若:

promise就是承若,说一不二,何为说以不二?见下例:

pormise
console.log

当resolve执行,状态就为成功,此后状态就不变了,我们看到后面跟了一个我干你大爷,但是状态没变。这就是承若。

我们发现,控制台第一个出现的是一个'promise',然后才是then的第一个回调执行。这就是此文一开始说的promise的特点。


Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例,接受一个数组作为参数,数组成员需要是promise对象,若不是,会转。数组成员全部成功,那么新Promise实例则成功,有一个失败,那就失败。若成功,resolve的参数是一个数组,成员为数组中成员的成功结果。弱失败,reject的参数就是失败成员的结果。


Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。只要有一个实例率先改变状态,新Promise的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给新Promise的回调函数。


Promise.resolve方法将参数转为Promise对象。

1.如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

2.参数是一个thenable对象,Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。thenable的执行结果会做为Promise对象的resolve的参数。见下例:

thenable

  如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的 Promise 对象,状态为resolved。参数为resolve的参数。


Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected。注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致。

    

                                                                                                    MDN

                                                                                                    MDN

                                                                                                    阮师傅

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