Promise 是 JS 对象,用于表示一个异步操作的最终完成 (或失败), 及其结果值
new Promise((resolutionFunc, rejectionFunc): void =>{ asynchronous operation })
returns a promise object. The promise object will be “fulfilled/rejected” when either of the functions resolutionFunc or rejectionFunc are invoked (比如resolve(33)
直接返回的是fulfilled-promise
;而setTimeout(()=>{resolve(33)},1000)
直接返回的是pendgin-promise
)
当 resolutionFunc 或 rejectionFunc 函数被调用时,它们分别对应 将 返回的 promise 变成fulfilled
orrejected
状态 需要执行的函数,接受一个 value 参数,作为.then(cb1,cb2) 的回调参数的入参
the code within the executor has the opportunity to perform some operation and then reflect the operation’s outcome (If the value is not another Promise object) as either “fulfilled” or “rejected” by terminating with an invocation of either the resolutionFunc or the rejectionFunc, respectively 别看 zh-CN 翻译 误导人
一个关于 event loop 的要点: ()内参数函数(resolutionFunc, rejectionFunc): void =>{ asynchronous operation }
是同步立即执行从 Promise 对象讲解事件循环机制
promise static property
Promise.all(iterableArray)
除 2 种特殊情况(空[]或不含 promise)外返回一个 pending-promise: 所有都成功会触发 fulfilled(res 是数组);否则 rejected 触发第一个失败的 promise 的 reject 回调Promise.any(iterableArray)
除 2 种特殊情况(空[]或不含 promise)外返回一个 pending-promise: 第一个成功会触发 fulfilled(res 是第一个 promise 的 res);都不成功的话才 返回异步失败和一个AggregateError
对象Promise.race(iterableArray)
返回一个 pending-promise: fulfilled & reject 都对应上第一个非 pending 状态的 promiseItem 的 fulfilled & rejectedPromise.allSettled(iterableArray)
返回一个数组,每个 item 对于 iterableArrayItem 的pending-promise
, 例:[ {status: "fulfilled", value: 33}, {status: "rejected", reason: Error: an error} ]
常用于 批量请求多次 api 的 场景,比如:批量改变 table 多行,每行一个 patch 的 api
Promise.resolve(promise / thenable-value / static-value)
返回一个 fulfilled-promise{status: fulfilled, result: static-value / promise / thenable-value}
例:Promise.resolve('xxxx').then(res=>{ console.log(res) }) // 'xxxx'
;
一个常用应用场景是: 当一个 parameter 既可以接受 promise 又可以接受 static-value 的时候就用 Promise.resolve,如 我的一开源项目用到- 如果是
thenable-value
比如(i.e. has a “then” method),例
thenable definition - 如果是
promise
,例
- 如果是
Promise.reject(reason)
返回一个 rejected-promise,例:Promise.reject(new Error('fail')).then(resolved, (result) { console.error(result) }); // Error: fail
promise 实例/原型属性
promiseXX.then(onFulfilled, onRejected)
- 两个函参
handler(param: promise.result):any
分别对应 this 的状态变化目标值触发的回调,其回调参数都有保底动作,一旦其不是个函数类型,内部会转换成标准 - 返回值是个 Promise,根据**then()**中的
onFulfilled 或 onRejected
函数的 return 分几种情况(以下以触发了 onFulfilled 为 assumption):这样就实现了 then 的链式调用handler(param): !Promise
:{status: fulfilled, result: resolve()-return-value}
handler(param): void
:{status: fulfilled, result: undefined}
handler(param): throw error
:{status: rejected, result: error}
handler(param): fulfilled-promise
:{status: fulfilled, result: promise's-fulfilled-value}
handler(param): rejected-promise
:{status: rejected, result: promise's-rejected-value}
handler(param): pending-promise
:{status: pending, result: promise-fulfilled/rejected-value}
// 见例 1
- 两个函参
promiseXX.catch()
返回值是 Promise and deals with rejected cases only. 可以部分理解成是 .then(null,onrejected)的别名.
根据 dot 前的promiseXX
的返回值 promise 状态 是否是rejected
来确定 trigger the catchobj.catch(onRejected)
实际上内部调用了obj.then(undefined, onRejected))
,所以使用 catch 的 onRejected 回调参数是 required
返回的 promise 状态:- 如果 catch 被触发了,其返回值 同 .then(_, onRejected) 对 onRejected 的判断逻辑,
- 否则返回 promiseXX 因为压根没 excute 到 catch 之后的代码
promiseXX.finally()
: 不管 Promise 对象最后状态如何,都会执行的操作
返回值是promiseXX
自身。见例 2
和.then()类似,但是有一个很大的不同点在于:return 的fulfilled/rejected-promise
的result
应用场景是:do some processing or cleanup once the promise is settled, regardless of its outcome
例 1:
const ppp = new Promise((res, reject) => {
reject("xx");
}).catch((e) => {
return new Promise((res) => {
setTimeout(() => {
res("aaaa");
}, 12000);
});
});
setTimeout(() => {
console.log(ppp); // Promise {<pending>} { [[PromiseState]]: "pending", [[PromiseResult]]: undefined }
}, 1000);
例 2
const an = new Promise((resolve) => {
resolve(3);
});
const bb = an.finally(() => {
console.log(an); // 后 Promise {<fulfilled>}
});
console.log(an, bb, an === bb); // 先 Promise {<fulfilled>}, Promise {<pending>}, false
Promise 相比 callback 解决了什么问题
- 可靠可信,promise 是原生支持的,相比自己实现的 让第三方函数内部逻辑判断 callback 的方式要可靠,promise 对象的状态 只能单向改变不可逆
- 多个相关 callback 嵌套的回调地狱,难以管理和 human-readable,promise 通过 .then 将代码 dock 在第一个异步命令上
- Promise 给 JS 带来了不一样的异步编程方式,但它本质上还是 callback,但是其特点是:
把一个个异步操作分别封装成合适的返回 Promise 的函数之后,我们可以借助 Promise 的特性来将一个一个异步操作函数组合起来,形成一个 Promise chain,这时才能发挥 Promise 的最大作用
https://github.com/NevenLeung/blog/issues/1
promise 的 reject 回调和 catch 的区别:
其实 reject 跟 catch 是一个东西,当同步的情况下,无论 throw 还是 reject 都会执行 onRejected 调用。区别在于 throw 不能用于异步调用中
比如new Promise((res,reject)=>{setTimeout(()=>{throw 'xxx'}, 1000)}).catch(funError)
不会触发 funError 被 catch 捕获,因为.catch 前的 variable 就永远是个 pending-promise (Promise Constructor 函参压根执行没有res
或reject
)
而 new Promise((res,reject)=>{setTimeout(()=>{reject 'xxx'}, 1000)}).catch(funError)
会触发 funError
手写 Promise
https://github.com/Hojondo/utils/blob/master/fake_promise.js