Promise 是什么,使用 Promise
先看 async
和 await
吧,然后混入 promise
从Promise
对象的方法和原型的方法上的返回和传入参数看
Promise 是什么, 主要介绍 Promise 构造函数
Promise 对象用于表示一个异步操作
的最终状态
(完成或失败),以及其返回的值
。
具体描述看下面
下面主要内容是
Promise
构造函数, 构造函数主要是用来包装还未支持promise
的函数
所以要new
一个
1 | var promise1 = new Promise(function(resolve, reject) { |
创建 Promise
Promise
对象是由关键字 new
及其构造函数
来创建的。该构造函数会把一个叫做“处理器函数”(executor function
)的函数作为它的参数
。这个“处理器函数”接受两个函数
——resolve
和 reject
——作为其参数。当异步任务顺利完成且返回结果值时(异步操作在executor
内),会调用 resolve
函数;而当异步任务失败且返回失败原因(通常是一个错误对象)时,会调用reject
函数。
高阶函数, 可以把函数作为参数或者返回函数 javascript-高阶函数
语法
1 | new Promise( function(resolve, reject) {...} /* executor */ ); |
参数就是一个 function(resolve, reject) {...}
这个executor
!注意, 这个
executor
不是用return
, 而是返回并执行resolve, reject
回调函数
!注意, 这个executor
不是用return
, 而是返回并执行resolve, reject
回调函数
!注意, 这个executor
不是用return
, 而是返回并执行resolve, reject
回调函数
executor
是带有 resolve
和 reject
两个参数的函数 。这两个参数也是函数. (回调函数哦)
Promise构造函数执行时立即调用 executor
函数( executor 函数在 Promise 构造函数返回新建对象前被调用), resolve
和 reject
两个函数作为参数传递给 executor
。executor 内部
通常会执行一些异步操作,
一旦完成,可以调用 resolve
函数来将 promise
状态改成 fulfilled
,或者在发生错误时调用reject
函数将它的状态改为 rejected
。 从这里知道, Promise 的状态是通过回调函数resolve
和reject
改的
即:resolve
和 reject
函数被调用时,分别将 promise
的状态改为 fulfilled
(完成)或 rejected
(失败)。
如果在 executor
函数中抛出一个错误,那么该 promise
状态为 rejected
。 executor
函数的返回值被忽略。
resolve
函数的作用是,将Promise
对象的状态从“未完成”变为“成功”(即从pending
变为resolved
),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject
函数的作用是,将Promise
对象的状态从“未完成”变为“失败”(即从pending
变为rejected
), 在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
描述
Promise
对象是一个代理对象(代理一个值),被代理的值在 Promise
对象创建时可能是未知的(比如可以是一个异步的操作,也可以直接是一个确定的值, 总之都用 Promise 包起来)。
它允许你为异步操作的成功和失败分别绑定相应的处理方法(handlers)。 这让异步方法可以像同步方法那样返回值,但并不是立即返回最终执行结果,而是一个能代表未来出现的结果的 promise
对象
一个 Promise
有以下 3 种状态: Promise 的状态是通过回调函数resolve
和reject
改的
pending
: 初始状态,既不是成功,也不是失败状态。fulfilled
: 意味着操作成功完成。对应从调用resolve
函数rejected
: 意味着操作失败。 对应从调用reject
函数
注意: 如果一个 promise 对象处在 fulfilled 或 rejected 状态而不是 pending 状态,那么它也可以被称为
settled
状态。
pending
状态的 Promise
对象可能触发 fulfilled
状态并传递一个值给相应的状态处理方法 resolve
,也可能触发失败状态(rejected
)并传递失败信息给 reject
方法 。
从这里看出, 先是执行第一个
Promise
对象,然后触发回调的方法resolve
reject
, 产生一个新的Promise
对象.
然后 👇 下面是Promise
对象原型上的方法来处理(就会被触发调用),用到then
catch
当其中任一种情况出现时,Promise
对象的 then
方法(这个方法是在 Promise 的原型上的, 并返回一个 Promise 对象)绑定的处理方法(handlers )就会被调用
( then
方法包含两个参数,也都是函数:onfulfilled
和 onrejected
,它们都是 Function
类型。当 Promise
状态为 fulfilled
时,调用 then
的 onfulfilled
方法,当 Promise
状态为 rejected
时,调用 then
的 onrejected
方法, 所以在异步操作的完成和绑定处理方法之间不存在竞争)。
这里搞懂, 第一个
Promise
通过执行executor
的回调函数resolve
reject
变为相应的fulfilled
或rejected
状态, 返回一个新的Promise
对象.
然后then
方法根据返回的新的Promise
对象的状态, 调用相应的onfulfilled
或onrejected
方法.
所以状态是 3 种, Promise 的回调函数 2 种, then 方法的回调也是 2 种
pending
fulfilled
rejected
resolve
reject
onfulfilled
onrejected
平时见到的 then
和 catch
可以链式调用的原因是因为 Promise.prototype.then
和 Promise.prototype.catch
方法返回 promise
对象
注意:
then
方法是在Promise
对象的原型上prototype
的,Promise
对象本身就 4 个方法resolve
reject
all
race
原型上 3 个then
catch
finally
属性和方法(上面涉及了 Promise 的方法和 Promise 原型上的方法, 具体介绍下)
看完方法和原型的返回, 在回顾去看下描述就更好
属性 不常用 2 个
Promise.length
length 属性,其值总是为 1 (构造器参数的数目).
Promise.prototype
表示 Promise 构造器的原型.
方法和原型
Promise
的方法 4 个, 都返回Promise
对象
Promise.resolve(value)
: 返回一个状态由给定value
决定的Promise对象
。
如果该value
是一个Promise
对象,则直接返回该Promise
对象;
如果该值是thenable
(即,带有then
方法的对象),返回的Promise
对象的最终状态由then
方法执行决定;(注意: 应该是Promise.resolve
方法会将这个对象转为Promise
对象,然后就立即执行thenable
对象的then
方法。)
1 | // 这是一个滴啊有then方法的对象, 所以 |
否则的话(该value
为空
,基本类型
或者不带then
方法的对象),返回的Promise
对象状态为fulfilled
,并且将该value
传递给对应的then
方法。
通常而言,如果你不知道一个值是否是Promise
对象,使用Promise.resolve(value)
来返回一个Promise
对象,这样就能将该value
以Promise
对象形式使用。
Promise.reject(reason)
: 返回一个状态为失败的Promise对象
,并将给定的失败信息reason
传递给对应的处理方法catch
住.(实际上只是then(null, ...)
的语法糖)Promise.all(iterable)
: 这个方法返回一个新的promise
对象(成功对应返回 resolve 一个 Promise 包装的所有成功 value 的数组, 失败就返回 reject 第一个失败的那个的 reason 信息),该promise
对象在iterable
参数对象里(不是说是数组
,而是说要具有iterable
接口)所有的promise
对象都成功的时候才会触发成功,一旦有任何一个iterable
里面的promise
对象失败
则立即触发该promise
对象的失败。这个
新的promise
对象在触发成功状态以后,会把一个包含iterable
里所有promise
返回值的数组
作为成功回调的返回值,顺序跟iterable
的顺序保持一致;如果这个新的promise
对象触发了失败状态
,它会把 iterable 里第一个触发失败的promise
对象的错误信息作为它的失败错误信息。Promise.all
方法常被用于处理多个promise
对象的状态集合。Promise.race(iterable)
: 当iterable
参数里的任意一个子promise
被成功或失败后(就是看最快的那个,all
相当于是看最慢的),父promise
马上也会用子promise
的成功返回值或失败详情作为参数调用父promise
绑定的相应句柄,并返回该promise
对象。(注意:Promise.race
在第一个promise
对象变为Fulfilled
之后,并不会取消其他promise
对象的执行。)
Promise
原型, 1 个属性, 3 个方法
属性就是原型都有的romise.prototype.constructor
返回被创建的实例函数. 默认为 Promise 函数
方法就是常见的 3 个, then
catch
finally
Promise.prototype.then(onFulfilled, onRejected)
: 添加解决(fulfillment
)和拒绝(rejection
)回调到当前promise
, 返回一个新的 promise
, 将以回调的返回值来resolve
. (catch
只是then
的一个特例)Promise.prototype.catch(onRejected)
: 添加一个拒绝(rejection
) 回调到当前promise
, 返回一个新的promise
。当这个回调函数被调用,新 promise
将以它的返回值来resolve
,否则如果当前promise
进入fulfilled
状态,则以当前promise
的完成结果作为新promise
的完成结果.注意这个也是返回一个 Promise, 当成then
只有第 2 个参数时呗Promise.prototype.finally(onFinally)
: 添加一个事件处理回调于当前promise
对象,并且在原promise
对象解析完毕后,返回一个新的promise
对象。回调会在当前promise
运行完毕后被调用,无论当前promise
的状态是完成(fulfilled
)还是失败(rejected
)
关于Symbol(Symbol.toStringTag): "Promise"
的知识, 看Symbol.toStringTag
总结 : 看你真的完全掌握了 promise 么?
Promise 对象用于表示一个异步操作
的最终状态
(完成或失败),以及其返回的值
。
Promise
编程的核心思想是如果数据就绪(settled
),那么(then
)做点什么。
Promise
构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。
1 | const promise = new Promise(function(resolve, reject) { |
resolve
函数的作用是,将Promise
对象的状态从“未完成”变为“成功”(即从pending
变为fulfilled
),在异步操作成功时调用,并将异步操作的结果,作为参数
传递出去;reject
函数的作用是,将Promise
对象的状态从“未完成”变为“失败”(即从pending
变为rejected
), 在异步操作失败时调用,并将异步操作报出的错误,作为参数
传递出去。
Promise
实例生成以后,可以用then
方法分别指定resolved
状态和rejected
状态的回调函数
。
1 | promise.then( |
立即resolve
的 Promise
对象,是在本轮“事件循环”(event loop
)的结束时,而不是在下一轮“事件循环”的开始时。
1 | setTimeout(function() { |
上面代码中,setTimeout(fn, 0)
在下一轮“事件循环”开始时执行,Promise. resolve()
在本轮“事件循环”结束时执行,console.log('one')
则是立即执行,因此最先输出。
特别说明:如果需要resolve()
往后传递多个参数,不能直接写resolve(a1,a2,a3)
,这样只能拿到第一个要传的参数,需要以数组或对象去传递
1 | let obj = { a1: a1, a2: a2, a3: a3 }; |
Promise 的链还停不了诶
1 | // 这里是返回一个pending状态的Promise |
虽然上面可以停住, 但会导致内存泄漏,毕竟一直停住了, 不释放内存.
衍生
Understand promises before you start using async/await 这个链接里面有 callback
转 promsie的
Implementing 这里有从头自己实现一个 promise
的