概念
promise本身不是异步的,而是用来管理异步编程,promise.then里面的方法才是异步的,resolve/reject是异步通知方法执行的微任务
promise实例的成功或者失败状态由以下几种情况来决定
new Promise中exector函数执行是否报错,报错则失败
resolve/reject,reject函数执行则失败
返回promise实例的then方法执行成功或者失败 类似p2 = p1.then(result => console.log(‘sfa’), reason =>console.log(‘sss’)),p2的状态由p1.then里面执行无论是result函数还是reason函数,只要不报错p2的状态就是成功
let p = new Promise((resolve, reject) => {// 修改状态和值的方法,但只会触发一次,如果状态已经不是pending了,则状态不会再修改// 如果这个回调函数执行报错,或者执行reject,那么报错信息就是实例是值,内部采用的是try/catch// resolve('OK')reject('NO')})
executor:可执行函数<br />在new Promise的时候executor函数立即执行<br />函数中一般用来管控一个异步编程代码<br />同时给executor传递两个函数,resolve/reject,这两个函数执行的时候同步修改promise实例的状态和值,并且通知then里面存放的方法放到异步微任务中执行,如果没有就只修改状态和值<br />p是一个Promise类的实例<br />内置私有属性:<br />[[PromiseState]]:实例状态,pending:准备状态 fulfield/resolved成功状态 rejected失败状态<br />[[PromiseResult]]:实例的值<br />属性/方法:<br />then<br />catch<br />finally<br />Symbol.toStringTag
then方法
执行then方法会返回一个全新的promise实例
几种不同的示例
let p = new Promise((resolve, reject) => {// exector函数立即执行,并且实例的状态时同步修改的console.log(1) // -> 1resolve('OK')console.log(2) // -> 2})console.log(p) // 此时实例状态已经是fulfield,值是OK -> 3// p.then(onFulfilledCallback, onRejectCallback)// p.then会做两件事情// + 将传递的onfulfilledCallback和onRejectCallback存储起来,可以基于then存储多个回调// + 验证实例状态// + 如果是pending状态,什么都不做// + 如果状态已经修改,则会通知对应的回调函数执行,但不是立即执行,基于事件队列中的异步微任务,将回调放到微任务队列中p.then((result) => {console.log(result, '成功执行') // -> 5}, (reason) => {console.log(reason, '失败执行')})console.log(3) // -> 4
let p = new Promise((resolve, reject) => {console.log(1) // -> 1// setTimeout存放了一个异步宏任务setTimeout(() => {resolve('ok')console.log(p) // -> 5console.log(4) // -> 6}, 1000)console.log(2) // -> 2})console.log(p) // 此时实例的状态还是pending状态 -> 3// p.then只是将回调函数存储起来p.then(result => {console.log(result, '成功执行') // -> 7}, reason => {console.log(reason, '失败执行')})console.log(3) // -> 4// 等到同步代码执行完成后,事件队列中只有一个宏任务,取出来执行// 当执行到resolve的时候,修改状态,通知实例回调函数执行,将其方法哦微任务中// 宏任务执行完成后,在取出微任务执行
let p1 = new Promise((resolve, reject) => {resolve('OK')})// p2是一个基于p1.then执行后返回全新的promise实例// 不论执行的是p1.then中onfulfilledCallback或者onrejectedCallback// + 不报错// + 如果返回一个promise实例,则根据promise实例的成功或者失败决定p2的成功或失败// 类似p2 = p1.then(result => {return Promise.resolve()/reject()或者new Promise(resolve=>{......})})// + 如果返回不是promise实例,则状态为成功,值为返回值// 类似 p2 = p1.then(result => console.log('sfa')) // 状态成功,值是undefined// + 报错// + p2的状态都是rejected,值是报错原因let p2 = p1.then(result => {console.log('P1成功', result)}, reason => {console.log('p1失败', reason)})let p3 = p2.then(result => {console.log('p2成功', result)}, reason => {console.log('p2失败', reason)})
then链
// 如果onfulfilledCallback/onrejectedCallback不传的话会“顺延/穿透”下一个同等状态的回调函数上// onfulfilledCallback: result => result// onrejectedCallback: reason => Promise.reject(reason)new Promise(resolve => {resolve('ok')}).then(null, /*result => result*/, null/*reject => Promise.reject(reject)*/).then(null, reason => {}).then(result => {})
catch
// 内部就是基于then链的“顺延/穿透”效果,默认onrejectedCallback不写,使用默认值,顺延到下一个同等状态的回调函数上new Promise((resolve, reject) => {reject('NO')}).then(result => result).then(result => result).catch(reason => {console.log(reason)})// catch的底层处理Promise.prototype.catch = function catch(onrejectedCallback){return this.then(null, onrejectedCallback)}
all
相当于ajax的并行:比如5个ajax请求,需要等到5个都成功了才会执行下一步操作
串行:5个ajax请求,第一个执行成功后执行第二个,第五个执行完成成功后下一步操作
// Promise.all([promise1, promise2, ...]) 接收一个promise数组,返回一个Promise实例A,成功还是失败取决于数组中每一个promise实例的执行,所有的promise成功,则A就是成功,否则就是失败/* Promise.all([p1, p2, p3]).then(result => {console.log(result) // 顺序和传递的顺序一致}).catch(reason => {console.log(reason) // 只要有一个失败,all立即为失败,结果就是当前实例失败的原因})*/let p1 = new Promise(resolve => {resolve('p1OK')})let p2 = new Promise(resolve => {resolve('p2 OK')})let p3 = new Promise((resolve, reject) => {setTimeout(() => {reject('p3 NO')}, 1000)})let p = Promise.all([p1, p2, p3]).then(result => {console.log(result, '成功')}).catch(reason => {console.log(reason, '失败') // 1000ms后输出NO})let pp = Promise.all([p1, p2]).then(result => {console.log(result, '成功') // ['p1 ok', 'p2 ok']}).catch(reason => {console.log(reason, '失败')})
race
// Promise.rac([promise1, promise2, ...]) 同样接收一个promise数组,返回一个Promise实例A,但是成功或者失败取决于promise数组执行,谁先返回就决定A的状态let p1 = new Promise(resolve => {resolve('p1 OK')})let p2 = new Promise(resolve => {resolve('p2 OK')})let p3 = new Promise((resolve, reject) => {setTimeout(() => {reject('p3 NO')}, 1000)})let p = Promise.race([p1, p2, p3]).then(result => {console.log(result, '成功')}).catch(reason => {console.log(reason, '失败') // 直接后输出OK})let p = Promise.race([p1, p2]).then(result => {console.log(result, '成功') // p1 ok}).catch(reason => {console.log(reason, '失败')})
