一、背景&学完可以收获什么
- 手写promise是很多大厂面试的必备题目
- 帮助我们从底层理解proimse,应对各种面试题,以及真实工作环境下解决问题。
- 浏览器机制,EventLoop,宏任务、微任务、Promise
- 知识储备
- js ==> 进阶课程
- es6
- es6
- 箭头函数 普通函数
- Promise基本了解
- promise是什么?
- Promise是js异步编程的新的解决方案
- 语法上来说promise是一个构造函数/类
- 功能上说:promise可以封装一个异步操作并可以获得结果
- promise基础语法
- const p = new Promise((resolve, reject) => {
setTimeout(function() {
reject('error')
}, 1000)
})
p.then(value => {
console.log('成功拿到了结果' + success);
},err => {
console.log(err)
})
- const p = new Promise((resolve, reject) => {
- 内部的状态改变
- Pending ==> resolve reject
- 默认为pending状态
- pending ==> resolved
- pending ==> rejected
- 状态只能改变一次
- 无论成功或者失败都会有一个结果,失败的结果一般成为reason,成功的结果一般叫做value
Promise A+ 规范
- Promise是一个类
- executor同步执行的函数, 传入两个函数resolve, reject,需要内部定义两个函数
- resolve和reject都需要传入成功的原因和失败的结果参数
- resolve调用会改变内部状态为resolved
- reject调用改变内部状态为rejected
- 定义then方法,传入两个函数参数,成功的回调以及失败的回调
- 内部有三个状态 pending ==> resolve || pending ==> reject(只能能从pending改变)
- 如果是resolve需要执行then的第一个参数(function)
- 如果是reject需要执行then后面第二个参数(function)
- onFulfilled || onRejected执行的时候还需要有参数,成功的结果或者失败的原因
- 只有在pending的时候状态才能改变
- 处理executor内部的错误,调用reject同时传入错误对象进去
- 处理异步调用的resolve & 并且能够多次调用then方法(then传进来的方法存起来,状态改变时候再去调用)
- then方法的两个参数必须都是异步执行的,不能再当前执行栈执行 可以使用queueMicrotask方法
链式调用
- 每次then都返回一个promise
- 如果上一次then里面的参数(onFulfilled/onRejected)调用返回的是基本值,使用函数的返回值resolve
- 如果代码抛错,使用错误原因reject
- 如果是promise,则使用promise执行的结果来处理如果x存在then方法就认为是一个promise
- 如果x为promise时候,
- 如果resolve为普通值,下次then也是调用resove处理
- resolve的值为promise需要继续等待promise完成作为下一次then的结果 (递归调用resolvePromise)
- 如果失败,直接调用下一次的reject即可
- 状态只能改变一次
5、如果then执行之后返回的promise,跟处理函数执行返回的promise为同一个值时候,使用reject:TypeError: Chaining cycle detected for promise # 5、穿透性,如果成功或者失败的回调不传function,使用默认值
测试用例代码
promises-aplus-tests
Promise.defer = Promise.deferred = function () { let dfd = {}; dfd.promise = new Promise(function (resolve, reject) {dfd.resolve = resolve;dfd.reject = reject; }); return dfd;};module.exports = Promise;
EventLoop