- call、apply、bind
- promise
- requireJS
- vue-router
- Array.prototype.indexOf()
- 柯里化、闭包、防抖节流
promise
promise里面的then函数仅仅是注册了后续需要执行的代码,真正的执行是在resolve方法里面执行的。
// promise的三种状态
// pending 任何回调之前
const PENDING = "pending"
// fulfuilled 成功回调
const FULFUILLED = "fulfuilled"
// rejected 失败回调
const REJECTED = "rejected"
// promise是类对象
class MyPromise {
constructor (excutor) {
// excutor异常处理
try {
// 外部excutor对象,传入两个函数对象,对应 reslove reject
excutor(this.reslove, this.reject)
} catch (error) {
this.reject(error)
}
}
// 初始化状态
status = PENDING
// 存放所有的成功回调函数
sucCallBack = []
// 存放所有的失败回调函数
failCallBack = []
value = undefined
reason = undefined
reslove = value => {
// 用于阻止非 pending 的调用(执行 resolve 和 reject 必须二选一)
if (this.status !== PENDING) return
this.status = FULFUILLED
this.value = value
// FIFO
while (this.sucCallBack.length) {
this.sucCallBack.shift()()
}
}
reject = reason => {
// 用于阻止非 pending 的调用(执行 resolve 和 reject 必须二选一)
if (this.status !== PENDING) return
this.status = REJECTED
this.reason = reason
// FIFO
while (this.failCallBack.length) {
this.failCallBack.shift()()
}
}
// 是能被链式调用的,因此then有返回值,是promise
then (sucCallBack, failCallBack) {
// then 参数变为可选
sucCallBack = sucCallBack ? sucCallBack : value => value
failCallBack = failCallBack ? failCallBack : reason => { throw reason }
// 需要返回新的promise,用于实现then 链式调用
let newPromise = new MyPromise((resolve, reject) => {
// 分情况讨论:同步 和 异步 回调处理
// 同步
// 调用then之前,同步status状态已发生变化
if (this.status === FULFUILLED) {
setTimeout(() => {
try {
// 成功回调函数
let newValue = sucCallBack(this.value)
resolvePromise(newPromise, newValue, resolve, reject)
} catch (error) {
// 在新promise中处理异常
reject(error)
}
}, 0);
}else if (this.status === REJECTED) {
setTimeout(() => {
try {
// 失败回调函数
let newValue = failCallBack(this.reason)
resolvePromise(newPromise, newValue, resolve, reject)
} catch (error) {
// 在新promise中处理异常
reject(error)
}
}, 0);
}
// 异步
else
{
// 异步status状态未发生变化,先对回调函数做保存
this.sucCallBack.push(() => {
setTimeout(() => {
try {
// 成功回调函数
let newValue = sucCallBack(this.value)
resolvePromise(newPromise, newValue, resolve, reject)
} catch (error) {
// 在新promise中处理异常
reject(error)
}
}, 0);
})
this.failCallBack.push(() => {
failCallBack
})
}
})
return newPromise
}
// 无论promise对象返回成功还是失败,finally都会被执行一次
// 只调用失败
catch (failCallBack) {
return this.then(undefined, failCallBack)
}
// all
// 对value进行promise包装,返回值为promise
static resolve(value) {
if (value instanceof MyPromise) {
return value
}
return new MyPromise(reslove=>{
reslove(value)
})
}
}
————————————————————————————————————————————————————————————————————
function resolvePromise(newPromise, newValue, resolve, reject) {
// 分情况讨论:
// 原promise(防止循环调用)
if (newPromise === newValue) {
// 在新promise中处理异常
reject("cycle call promise")
}
// MyPromise
if (newValue instanceof MyPromise) {
// 将状态传递给下一个promise对象
// 🌰 ---- 实现then链式异步顺序调用
// newValue.then(value=>resolve(value),value=>reject(value))
newValue.then(resolve,reject)
}
// 普通值
else
{
// 在新promise中处理成功回调
resolve(newValue)
}
}
module.exports = MyPromise
// 无论promise对象返回成功还是失败,finally都会被执行一次
finally (callback) {
// then 的返回值是promise
// 不管value是promise对象还是普通值,一律返回promise对象,保证异步promise的执行顺序
return this.then(value => {
return MyPromise.resolve(callback()).then(()=>value)
},reason => {
return MyPromise.resolve(callback()).then(()=>{throw reason})
})
}
// 处理异步并发,按照异步代码调用顺序得到异步代码执行结果,参数为数组,数组值的顺序即结果的顺序,返回值也是promise对象
static all(array) {
let result = []
let index = 0
return new MyPromise((resolve, reject)=>{
function addData(key, value) {
result[key] = value
index ++
// 保证所有(同步于异步)结果都获取到后,在resolve
if (index === array.length) {
resolve(result)
}
}
array.forEach((item, index) => {
if (item instanceof MyPromise) {
// promise对象
item.then(value=>addData(index,value),reason=>reject(reason))
}
else
{
// 普通值
addData(index, item)
}
})
})
}
Promise的实现过程,其主要使用了设计模式中的观察者模式:
- 通过Promise.prototype.then和Promise.prototype.catch方法将观察者方法注册到被观察者Promise对象中,同时返回一个新的Promise对象,以便可以链式调用。
- 被观察者管理内部pending、fulfilled和rejected的状态转变,同时通过构造函数中传递的resolve和reject方法以主动触发状态转变和通知观察者。
function Promise(exector) {
let self = this;
//status表示一种状态
let status = "pending";
let value = undefined;
let reason = undefined;
//成功执行
function resolve(value) {
if (status == 'pending') {
self.value = value;
self.status = "resolve";
}
}
//执行失败
function reject(reason) {
if (status == 'pending') {
self.reason = reason;
self.status = "reject"
}
}
//对异常操作
try {
exector(resolve, reject)
} catch (e) {
reject(e)
}
//设置promise的then方法
Promise.prototype.then = function (reject, resolve) {
let self = this;
if (this.status == 'resolve') {
reject(self.value)
}
if (this.status == 'reject') {
resolve(self.reason)
}
}
}
//new 一个promise 进行测试
let promise = new Promise((reject, resolve) => {
resolve("return resolve");
});
promise.then(data => {
console.log(`success${data}`);
}, err => {
console.log(`err${err}`);
})
promise.all
// 手写Promise.all()
Promise.property.all = function (iterators) {
const promises = Array.from(iterators);
const len = promises.length;
let count = 0;
let resultList = [];
return new Promise((resolve, reject) => {
promises.forEach((p, index) => {
// 包一层,以兼容非promise的情况
Promise.resolve(p).then((result) => {
resultList[index] = result;
count++;
if (count === len) resolve(resultList);
}).catch(e => {
reject(e);
})
})
})
}