关于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对象,注意,是新的!


栗子:

关于Promise_第1张图片

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

cosole.log

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

看下例是如何失败的:

关于Promise_第2张图片
promise

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

console.log

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


划重点:

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

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

见下例:

关于Promise_第3张图片
promise

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

关于Promise_第4张图片
console.log

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

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


Promise.prototype.catch(fun(x))

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

关于Promise_第5张图片
catch
console.log

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

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

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


关于承若:

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

关于Promise_第6张图片
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的参数。见下例:

关于Promise_第7张图片
thenable

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


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

    

                                                                                                    MDN

                                                                                                    MDN

                                                                                                    阮师傅

你可能感兴趣的:(关于Promise)