导航
[深入01] 执行上下文
[深入02] 原型链
[深入03] 继承
[深入04] 事件循环
[深入05] 柯里化 偏函数 函数记忆
[深入06] 隐式转换 和 运算符
[深入07] 浏览器缓存机制(http缓存机制)
[深入08] 前端安全
[深入09] 深浅拷贝
[深入10] Debounce Throttle
[深入11] 前端路由
[深入12] 前端模块化
[深入13] 观察者模式 发布订阅模式 双向数据绑定
[深入14] canvas
[深入15] webSocket
[深入16] webpack
[深入17] http 和 https
[深入18] CSS-interview
[深入19] 手写Promise
[深入20] 手写函数
[react] Hooks
[部署01] Nginx
[部署02] Docker 部署vue项目
[部署03] gitlab-CI
[源码-webpack01-前置知识] AST抽象语法树
[源码-webpack02-前置知识] Tapable
[源码-webpack03] 手写webpack - compiler简单编译流程
[源码] Redux React-Redux01
[源码] axios
[源码] vuex
[源码-vue01] data响应式 和 初始化渲染
[源码-vue02] computed 响应式 - 初始化,访问,更新过程
前置知识
一些单词
race:比赛,竞赛
Settled:结束
execute:执行
executor:执行者
detected:检测
promise复习
- 方法
- promise.then() ---------------------------- 返回新的promise
- promise.catch() --------------------------- 返回新的promise
- promise.finally() -------------------------- 不管状态如何都会执行
- promise.all() ------------------------------ 所有resolve则fulfilled,一个reject则rejected
- promise.any() ---------------------------- 一个resolve则fulfilled,所有reject则rejected
- promsie.race() ---------------------------- 第一个resolve则fulfiled,第一个reject则rejected
- 特点
- 对象的状态不受外界影响,只有异步操作的结果才可以决定当前是哪一种状态,任何其他操作都不能改变这个状态
- 状态一旦改变就不会再变,任何时候都可以得到这个结果
- 缺点
- 无法取消promise,一旦新建就会立即执行,中途无法取消
- 如果不设置回调,内部抛出的错误,不会反应到外部
- 当处于pending状态时,无法得知当前进展到哪一个阶段 ( 刚开始?即将结束?)
- Promise的用法
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(value) {
// success
}, function(error) {
// failure
});
说明:
(1) Promise构造函数接受一个 ( 函数 ) 作为参数
(2) ( 参数函数 ) 又接受两个函数作为参数 ( resolve函数 ) 和 ( reject函数 )
(3) resolve()
- 函数是在状态由 pending->fulfilled 时,即成功时调用,并将异步操作的结果作为参数传递出去
- resolve()函数的参数,除了是正常的 ( 值 ) 以外,还可以是一个 ( promise实例 )
(4) reject()
- 函数是在状态由 pending->rejected时,即失败时调用,并将异步操作报出的错误作为参数传递出去
- reject()函数的参数,通常是 ( Error对象 ) 的实例
(5) then() 方法接受两个函数作为参数
- 第一个参数函数在resolve时被调用
- 第二个参数函数在reject时被调用,参数分别是终值和拒因,第二个参数函数可选
- resolve()
- resolve()和reject()两个函数并不会终止promise,后面的代码还是会执行
- 通常用 return resolve() return reject() 这样的方式结束promise构造函数代码的运行
- resolve() 函数的参数是一个promise实例的情况
let count = 1
setInterval(() => {console.log(count++)}, 1000)
const p1 = new Promise(function (resolve, reject) {
setTimeout(() => {
console.log('p1中的代码开始执行')
reject(new Error('fail'))
}, 3000)
})
const p2 = new Promise(function (resolve, reject) {
setTimeout(() => {
console.log('p2中的代码开始执行');
resolve(p1)
}, 1000)
})
p2
.then(result => console.log(result))
.catch(error => console.log(error))
分析:
(1) p2的状态在 1s 后改变为成功,resolve(p1)的参数p1还是一个promise,导致p2的状态失效
(2) p2的状态失效,则p2的状态由p1决定
(3) p1的状体在 3s 后改变为失败, reject(new Error('fail')),所以在 3s 后,p2的状态也变成了失败
(4) p2的失败状态由 p2.catch()捕获
- then()
- 返回一个新的promise实例,因此可以采用链式写法
- 如果then()方法链式调用,上一个then()可能返回的是一个promise实例,则后一个then()的回调函数需要等待前一个then()状态改变后才会调用
- catch()
- 返回一个新的promise实例,主要作用是捕获promise过程中的错误
- catch()方法返回的是一个promise对象,因此.catch()后面可以继续调用.then()
- catch()是
.then(null, rejection)
或.then(undefined, rejection)
的别名,用于指定发生错误
时的回调函数
- 只要是catch()前面的then()和promise内部抛出的错误都能被catch()捕获
- 注意:
- 一个在then()中只需要添加成功状态后的回调,而失败的状态由catch()来负责捕获
- finally()
- 不管promise对象最后是什么状态,都会执行的操作
- finally()的回调函数不接受任何参数,因为finally()的回调函数中的操作和状态无关
- all()
- 所有resolve()则fulfilled,一个reject()则rejected
- any()
- 一个resolve()则fulfilled,所有reject()则rejected
- 和all()相反
- race()
- 一个resolve()则fulfilled,一个reject()则rejected
- allSettled()
- 在所有参数的实例都返回结果时,包装实例才会结束
- 比如等待所有请求完成,无论成功失败,都结束loading动画
手写Promise
class Promise {
constructor(executor) {
// 参数不是函数,报错
if (typeof executor !== 'function') {
throw new TypeError(`Promise resolver ${executor} is not a function`)
}
this.init() // 初始化值
try {
executor(this.resolve, this.reject)
} catch (err) {
// 使用 try...catch 的目的是为了把executor()中的错误抛出给then的回调去捕获
this.reject(err)
}
}
init = () => {
this.value = null // 终值
this.reason = null // 拒因
this.state = Promise.PENDING // 状态
this.onFulfilledCallbacks = [] // 成功回调, 在then()方法中push,resolve()时执行
this.onRejectedCallbacks = [] // 失败回调,在then()方法中push,reject()时执行
}
resolve = (value) => {
// 成功后的一系列操作 (状态的改变,成功回调的执行 )
// 状态的改变:pending -> fulfilled
// console.log(this.constructor === Promise) // true
// this 在箭头函数中,作用域绑定在父级执行上下文,即定义时所在的对象
// 即this相当于父级的this,这里又是在勾走函数中,所以this指向了实例对象
if (this.state === Promise.PENDING) {
this.state = Promise.FULFILLED
this.value = value
this.onFulfilledCallbacks.forEach(fn => fn(this.value))
// 当promise的参数函数中有异步操作时,then方法会优先于resolve()或者reject()先执行
// 这样就是导致执行then()方法时,状态是pending状态,因为状态的改变是在resolve()或reject()中改变的,而他们因为异步都没执行
// 这是需要用一个数组来存储将来才会执行的onFulfilled函数
// 这里push进onFulfilledCallbacks的函数,将在resolve()函数中去执行
}
}
reject = (reason) => {
// 失败后的一系列操作 (状态的改变,失败回调的执行 )
// 状态的改变:pending -> rejected
if (this.state === Promise.PENDING) {
this.state = Promise.REJECTED
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn(this.reason))
}
}
then = (onFulfilled, onRejected) => {
// 参数校验,穿透效果,即then不传任何参数具有穿透效果
if (typeof onFulfilled !== 'function') {
onFulfilled = value => value
}
// 参数校验,穿透效果,即then不传任何参数具有穿透效果
if (typeof onRejected !== 'function') {
onRejected = reason => {
throw reason
}
}
// then()方法返回的是一个新的 promse 实例
// 因为返回新的promise实例,可以可以实现链式调用
let promise2 = new Promise((resolve2, reject2) => {
// 执行onFulfilled函数的条件
if (this.state === Promise.FULFILLED) {
setTimeout(() => {
// 这里中间的then()方法中的回调 onFulfilled() 函数是有返回值的
// 中间then()参数函数onFulfilled()的返回值,会被当做下一个then回调的参数传入
try {
const x = onFulfilled(this.value)
Promise.resolvePromise(promise2, x, resolve2, reject2)
} catch (err) {
reject2(err)
}
})
}
if (this.state === Promise.REJECTED) {
setTimeout(() => {
try {
const x = onRejected(this.reason)
Promise.resolvePromise(promise2, x, resolve2, reject2)
} catch (err) {
reject2(err)
}
})
}
if (this.state === Promise.PENDING) {
// 如果状态是 pending
// 当promise的参数函数中有异步操作时,then方法会优先于resolve()或者reject()先执行
// 这样就是导致执行then()方法时,状态是pending状态,因为状态的改变是在resolve()或reject()中改变的,而他们因为异步都没执行
// 这时需要用一个数组来存储将来才会执行的onFulfilled函数
// 这里push进onFulfilledCallbacks的函数,将在resolve()函数中去执行
this.onFulfilledCallbacks.push((value) => {
// 这里仍然需要使用setTimeout,因为这个函数是在resolve()中执行的,如果resolve()后面任然后同步代码,要保证同步代码先执行
setTimeout(() => {
try {
const x = onFulfilled(value)
Promise.resolvePromise(promise2, x, resolve2, reject2)
} catch (err) {
reject2(err)
}
})
})
this.onRejectedCallbacks.push((reason) => {
setTimeout(() => {
try {
const x = onRejected(reason)
Promise.resolvePromise(promise2, x, resolve2, reject2)
} catch (err) {
reject2(err)
}
})
})
}
})
return promise2
}
}
// 这里使用静态属性,是为了避免 魔法字符串
Promise.PENDING = 'pending'
Promise.FULFILLED = 'fulfilled'
Promise.REJECTED = 'rejected'
Promise.resolvePromise = function (promise2, x, resolve, reject) {
// x 与 promise2 相等
if (promise2 === x) {
reject(new TypeError('chainning cycle detected for promise'))
}
// x 是 Promise
if ( x instanceof Promise) {
x.then(value => {
// resolve(value)
Promise.resolvePromise(promise2, value, resolve, reject)
}, reason => {
reject(reason)
})
}
else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
// x 为对象或函数
try {
const then = x.then
if (typeof then === 'function') {
then.call(
x,
value => {
if (called) return
called = true
MyPromise.resolvePromise(promise2, value, resolve, reject)
},
reason => {
if (called) return
called = true
reject(reason)
}
)
} else {
if (called) return
called = true
resolve(x)
}
} catch (e) {
if (called) return
called = true
reject(e)
}
} else {
resolve(x)
}
}
const promise = new Promise((resolve, reject) => {
// throw new Error('出错了')
console.log(1)
setTimeout(() => {
console.log(4)
resolve(6)
console.log(5)
})
console.log(2)
})
.then(
value => {
console.log(value, 'value')
return new Promise(resolve => {
resolve(new Promise(resolve3 => {
resolve3(7)
}))
})
},
reason => {
console.log(reason, 'reason')
})
.then(
value => {
console.log(value, 'vvvvvvvvvvvv')
}, reason => {
console.log(reason)
})
console.log(3)
// then
// then中的两个参数回调函数需要异步,setTimeout解决
// 如果promise参数函数内部抛出错误,需要在then()中捕获 => try ... catch
// 如果promise中存在异步,then的回调不会执行 => 因为在执行then方法的时,state === 'pending' 不满足执行then两个回调的任何一个,而当setTimeout中的 resolve() 执行的时,then执行过了就不会再继续执行
new Promise()的参数必须是函数,非函数时会报错
原生:
new Promise(1)
TypeError: Promise resolver 1 is not a function
模拟实现:
class Promise {
constructor(executor) {
if (typeof executor !== 'function') {
// 参数必须是函数,不是函数抛出错误
throw new TypeError(`Promise resolver ${executor} is not a function`)
}
executor(this.resolve, this.reject)
}
}
const promise = new Promise()
// TypeError: Promise resolver undefined is not a function
resolve()方法的主要作用
- (1) 把状态 ( status ) 从 ( pending -> fulfilled )
- (2) 把终值 ( value ) 赋值为 resolve()函数传入的 ( 参数 )
- (3) 把 ( onFulfilledCallback数组 ) 中的函数,依此取出执行
- 如果promise中存在异步操作时,then()比resolve()先执行
- 所以在then()方法中,需要向onFulfilledCallback数组中push进一个将来在resolve()中才会执行的函数
rejected()方法的主要作用
- (1) 把状态 ( status ) 从 ( pending -> rejected )
- (2) 把拒因 ( value ) 赋值为 reject()函数传入的 ( 参数 )
- (3) 把 ( onRejectedCallback数组 ) 中的函数,依此取出执行
- 如果promise中存在异步操作时,then()比resolve()先执行
- 所以在then()方法中,需要向onFulfilledCallback数组中push进一个将来在reject()中才会执行的函数
class Promise {
constructor(executor) {
if (typeof executor !== 'function') {
// 参数必须是函数,不是函数抛出错误
throw new TypeError(`Promise resolver ${executor} is not a function`)
}
this.init()
executor(this.resolve, this.reject)
}
init = () => {
this.value = null // 终值,初始化
this.reason = null // 拒因,初始化
this.status = Promise.PENDING // 状态,初始化时pending
this.onFulfilledCallbacks = [] // 成功回调, 在then()方法中push,resolve()时执行
this.onRejectedCallbacks = [] // 失败回调,在then()方法中push,reject()时执行
}
resolve = (value) => {
if (this.status === Promise.PENDING) {
this.status = Promise.FULFILLED
this.value = value
this.onFulfilledCallbacks.forEach(fn => fn(value))
}
}
reject = (reason) => {
if (this.status === Promise.PENDING) {
this.status === Promise.REJECTED
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn(resaon))
}
}
then = (onFulfilled, onRejected) => {
if (this.status === Promise.FULFILLED) {
onFulfilled(this.value)
}
if (this.status === Promise.REJECTED) {
onRejected(this.reason)
}
if (this.status === Promise.PENDING) {
this.onFulfilledCallbacks.push((value) => onFulfilled(value))
this.onRejectedCallbacks.push((reason) => onRejected(reason))
}
}
}
Promise.PENDING = 'pending'
Promise.FULFILLED = 'fulfilled'
Promise.REJECTED = 'rejected'
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
})
}).then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
then()方法没有传参时
- 需要重写 onFulfilled函数,返回当前的终值 this.value
- 需要重写 onRejected函数,返回当前的拒因 this.reason,并抛出
then = (onFulfilled, onRejected) => {
if (typeof onFulfilled !== this.FUNCTION) {
// 没传onFulfilled参数,就重写该函数
// 将调用参数原样返回
// 这里没有直接写 (typeof onFulfilled !== 'function') 防止魔法字符串
onFulfilled = value => value
}
if (typeof onRejected !== this.FUNCTION) {
// 没传onRejected参数,就重写该函数
// 抛出reason
onRejected = reason => {
throw reason
}
}
if (this.status === this.FULFILLED) {
// 是fulfilled状态是,才执行onFulfilled函数,参数是当前的终值
// 即状态改变时为成功时,添加的回调函数
// 这里传参和没有传参都会执行,没传参是执行重写过后的onFulfilled
onFulfilled(this.value)
}
if (this.status === this.REJECTED) {
onRejected(this.reason)
}
}
then()保证执行顺序1
- then()需要在同步代码执行完后,then()中的回调函数才能执行
console.log(1)
const promise = new Promise((resolve, reject) => {
console.log(2)
resolve(5)
console.log(3)
})
.then(value => {
console.log(value)
}, reason => {
console.log(reason)
})
console.log(4)
问题:如何保证执行顺序是 12345
解决:then()是异步方法,即then()方法的参数回调需要在resolve()或reject()方法执行后才执行,用 ( 定时器 ) 解决
说明:如果不用定时器执行顺序是
then = (onFulfilled, onRejected) => {
if (typeof onFulfilled !== Promise.FUNCTION) {
onFulfilled = value => value
}
if (typeof onRejected !== Promise.FUNCTION) {
onRejected = reason => reason
}
if (this.status === Promise.FULFILLED) {
setTimeout(() => { // 用setTimeout()来模拟异步执行onFulfilled,保证同步代码执行后再执行onFulfilled
onFulfilled(this.value)
})
}
if (this.status === Promise.REJECTED) {
setTimeout(() => { // 用setTimeout()来模拟异步执行onRejected,保证同步代码执行后再执行onRejected
onRejected(this.reason)
})
}
if (this.status === Promise.PENDING) {
this.onFulfilledCallbacks.push((value) => onFulfilled(value))
this.onRejectedCallbacks.push((reason) => onRejected(reason))
}
}
then()保证执行顺序2
- 当promise中有有异步代码时,then()方法会比resolve()先执行,此时statuss='pending'状态
- 而在then方法中并未添加状态是pending状态时的相关操作时,then()中的两个回调都不会执行
console.log(1)
new Promise((resolve, reject) => {
console.log(2)
setTimeout(() => resolve())
// 当这里有异步操作时,上面的代码打印只有 123,注意 4 并未打印
// 原因是then()方法在resolve()方法前执行了,因为resolve是异步的,导致 then() 中的状态还是 pending 状态
// 而在then方法中并为添加状态是pending状态时的相关操作
}).then(() => console.log(4))
console.log(3)
问题:打印出了123,但是并未打印4
分析:
1. 原因是then()方法在resolve()方法前执行了,因为resolve是异步的,导致 then() 中的状态还是 pending 状态
2. 而在then方法中并为添加状态是pending状态时的相关操作
解决:
1. 在then()方法中添加pending状态下的相关判断
- 并向 onFulfilledCallbacks 数组中push一个方方法,该方中去调用 onFulfilled 方法,参数是当前的value
- 并向 onRejectedCallbacks 数组中 push 一个方法,该方中去调用 onRejected 方法,参数是当前的reason
2. 在resolve()方法中去循环 onFulfilledCallbacks 数组,并执行里面的函数,实参是 this.value
2. 在reject()方法中去循环 onRejectedCallbacks 数组,并执行里面的函数,实参是 this.reason
then = (onFulfilled, onRejected) => {
...
if (this.status === this.PENDING) {
// pending状态push函数到onFulfilledCallbacks数组
this.onFulfilledCallbacks.push(value => onFulfilled(value))
this.onRejectedCallbacks.push(reason => onRejected(reason))
}
}
resolve = (value) => {
if (this.status === this.PENDING) {
this.status = this.FULFILLED
this.value = value
this.onFulfilledCallbacks.forEach(fn => fn(this.value)) // 执行数组中的函数,并传入实参
}
}
reject = (reason) => {
if (this.status === this.PENDING) {
this.status = this.REJECTED
this.reason = reason
this.onRejectedCallbacks.forEach(fn => fn(this.reason))
}
}
then()保证执行顺序3
console.log(1)
new Promise((resolve, reject) => {
console.log(2)
setTimeout(() => {
resolve()
console.log(4) // 要保证4比5先执行,因为4是同步代码
})
}).then(() => console.log(5))
console.log(3)
问题:上面代码输出 12354 , 而真正的promise应该输出 12345
分析:因为resolve()后面还有同步代码,要保证后面的同步代码先执行
解决:在向 onFulfilledCallbacks数组中push方法时,要再用 setTimeout包装,让resolve()后面的代码先执行
then = (onFulfilled, onRejected) => {
...
if (this.status === this.PENDING) {
this.onFulfilledCallbacks.push(value => {
setTimeout(() => { // 再用setTimeout包装,保证resolve()后面的代码先于 then的回调函数 执行
onFulfilled(value)
}, 0)
})
this.onRejectedCallbacks.push(reason => {
setTimeout(() => {
onRejected(reason)
}, 0)
})
}
}
then() 的链式调用
- then()方法返回的是新的promise实例,注意不是原来的,所以可以链式调用
- 新的promise中参数函数的resolve的是onFufiled函数执行后返回的值
then = (onFulfilled, onRejected) => {
// 参数校验,穿透效果,即then不传任何参数具有穿透效果
if (typeof onFulfilled !== Promise.FUNCTION) {
onFulfilled = value => value
}
// 参数校验,穿透效果,即then不传任何参数具有穿透效果
if (typeof onRejected !== Promise.FUNCTION) {
onRejected = reason => reason
}
const promise2 = new Promise((resolve2, reject2) => {
if (this.status === Promise.FULFILLED) {
setTimeout(() => {
const x = onFulfilled(this.value)
// 将onFulfilled函数的返回值作为resolve()的参数,传给新的 then() 方法
resolve2(x)
})
}
if (this.status === Promise.REJECTED) {
setTimeout(() => {
const x = onRejected(this.reason)
reject2(x)
})
}
if (this.status === Promise.PENDING) {
this.onFulfilledCallbacks.push((value) => {
setTimeout(() => {
const x = onFulfilled(value)
resolve2(x)
})
})
this.onRejectedCallbacks.push((reason) => {
setTimeout(() => {
const x = onRejected(reason)
reject2(x)
})
})
}
})
return promise2
}
更详细
then = (onFulfilled, onRejected) => {
if(typeof onFulfilled !== 'function') {
onFulfilled = (value) => value
}
if(typeof onRejected !== 'function') {
onRejected = (reason) => {
throw reason
}
}
const promise2 = new Promise((resolve, reject) => {
if (this.status === Promise.FULFILLED) {
setTimeout(() => {
try {
const x = onFulfilled(this.value) // 将onFulfilled函数的返回值作为resolve()的参数,传给新的 then() 方法
resolve(x) // promise2的resolve的时机
} catch(err) {
reject(err) // promise2的reject的时机
}
})
}
if (this.status === Promise.REJECTED) {
setTimeout(() => {
try {
const x = onRejected(this.reason)
resolve(x)
} catch (err) {
reject(err)
}
})
}
if (this.status === Promise.PENDING) {
this.onFulfilledCallbacks.push((value) => {
setTimeout(() => {
try {
const x = onFulfilled(value)
resolve(x)
} catch(err) {
reject(err)
}
})
})
this.onRejectedCallbacks.push((reason) => {
setTimeout(() => {
try {
const x = onRejected(reason)
resolve(x)
} catch(err) {
reject(err)
}
})
})
}
})
return promise2
}
Promise.all()模拟实现
p = Promsie.all([p1, p2, p3])
- 返回值:Promise.all() 返回一个新的promise实例
- 参数:
- ( 参数 ) 是一个 ( 数组 ) 或者是具有 ( Iterator ) 接口类型的数据,成员都是promsie实例
- 如果不是promsie实例就会调用Promsie.resolve()转成promsie实例
- 作用:
- 如果所有参数数组成员的状态,都变成了fulfilled,则整个状态变成fulfilled
- 此时 p1,p2,p3中resolve()的返回值,将组成一个数组,传递给p的回调函数
- 如果有一个参数数组成员的状态变成了rejected,则整个状态变成了rejected
- 此时,第一个被拒绝的reject()的返回值,会传递给p的回调函数
- 如果所有参数数组成员的状态,都变成了fulfilled,则整个状态变成fulfilled
说明:
1. Promise.all()返回的是一个新的promise,即可以使用then获取resolve和reject的结果
2. 参数是一个数组或者具有Iterator接口的数据
3. 如果参数数组成员不是promise,就会被Promise.resolve()转成promise对象
4. resolve的时机是所有参数成员都变成fulfilled状态时
5. reject的时机是只要有一个rejected状态时
Promise.all = (promises) => {
// 返回一个新的promise实例
return new Promise((resolve, reject) => {
const arr = []
let count = 0 // 记录fulfilled状态的promise个数
const promiseArr = Array.from(promises) // 参数除了数组还可以是具有Iterator接口的数据类型
const len = promiseArr.length
for (let i = 0; i < len; i++) {
Promise.resolve(promiseArr[i]).then(value => { // 如果参数不是promise,会调用Promise.resolve()转成promise
count ++ // 进入这里,表示成功的回调,即fulfilled状态
arr[i] = value // 将该成功的promise装进数组
if (count === len) {
console.log(count, 'count')
resolve(arr)
// 如果count和数组总长度相等,说明都是fulfilled状态了
// 所有resolve的时机就是所有都变成fulfilled状态是resolve
}
}, reject) // 这里写的不完善,请看下面的最新补充
}
})
}
const a = Promise.resolve(1)
const b = Promise.resolve(2)
const c = new Promise(resolve => {
setTimeout(() => {
resolve(33)
})
})
Promise.all([a, b, c]).then(value => console.log(value, 'value'))
2021/4/7修改 Promise.all 模拟实现
Document
Proimse.race()模拟实现
Promise.race = (promises) => {
return new Promise((resolve, reject) => {
const promiseArr = Array.from(promises)
const len = promises.length
for(let i = 0; i < len; i++) {
Promise.resolve(promiseArr[i]).then(value => {
resolve(value) // 直接resolve第一个then是成功时的回调函数接收到的终值
})
}
})
}
总结遇到的一些面试题 2021/04/10
(1) promise面试题1
Document
(2) promise面试题2
Document
资料
手写promise https://segmentfault.com/a/1190000012820865
手写promise https://juejin.im/post/6844903872842956814