异步编码规范
异步编码规范
- 手写promise
- promise A+ 规范
- async await 原理
- generator -- 忽略
Promise
1.特点
1.1 状态不可逆转==》不可从一个状态变为另外一个状态
promise的方法
- finally
finally 方法没有参数,也不会改变 Promise 的状态,它只是在 Promise 结束时提供了一个通知机制,
让我们可以在 Promise 结束后执行一些清理工作(比如操作文件的时候关闭文件流)。
- all
接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
每一个promise执行成功resolve,最后才执行成功(返回一个Promise实例),进入then,否则失败进入catch
- allSettled
接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
每个promise状态改变成fulfilled或者rejected之后返回,返回的是一个数组对象,对象中有状态status和每一项的返回结果value;
- race
以快为准,数组中所有的promise对象,有一个先执行了何种状态,该对象就为何种状态,并执行相应函数
接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
其中有一个promise返回了,不管是fulfilled或者rejected,直接返回这个promise的结果
- any
接受一个具有Iterable接口的类型,如数组,Map,Set,传入多个promise,
当传入的任何一个promise成功的时候,不管其他是否成功或者失败,会把成功的那个promise返回
手写promise的实现
class MyPromise {
constructor(executor) {
this.initValue();
this.initBind();
try {
executor(this.resolve, this.reject);
} catch (error) {
this.reject(error);
}
}
initValue() {
this.promiseStatus = 'pending';
this.promiseResult = null;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
}
initBind() {
this.resolve = this.resolve.bind(this);
this.reject = this.reject.bind(this);
}
resolve(value) {
if (this.promiseStatus !== 'pending') {
return;
}
this.promiseStatus = 'fulfilled';
this.promiseResult = value;
this.onFulfilledCallbacks.forEach(fn => fn(this.promiseResult))
}
reject(reason) {
if (this.promiseStatus !== 'pending') {
return;
}
this.promiseStatus = 'rejected';
this.promiseResult = reason;
this.onRejectedCallbacks.forEach(fn => fn(this.promiseResult))
}
then(onFulfilled, onRejected) {
//参数校验 确保then的两个参数都是函数
onFulfilled =
typeof onFulfilled === 'function'
? onFulfilled
: val => val;
onRejected =
typeof onRejected === 'function'
? onRejected
: reason => { throw reason }
// 实现链式调用
const thenPromise = new MyPromise((resolve, reject) => {
const resolvePromise = cb => {
try {
const x = cb(this.promiseResult)
if (x === thenPromise) {
// 不能返回自身哦
throw new Error('不能返回自身。。。')
}
if(x instanceof MyPromise){
x.then(resolve, reject)
}else{
resolve(x)
}
} catch (error) {
reject(error);
throw new Error(error)
}
}
if (this.promiseStatus === 'fulfilled') {
resolvePromise(onFulfilled);
} else if (this.promiseStatus === 'rejected') {
resolvePromise(onRejected);
} else if (this.promiseStatus === 'pending') {
this.onFulfilledCallbacks.push(resolvePromise.bind(this,onFulfilled));
this.onRejectedCallbacks.push(resolvePromise.bind(this,onRejected));
}
})
return thenPromise
}
}
const p1 = new MyPromise((resolve, reject) => {
// 不能确定3秒后执行then方法,但是可以保证在3秒后执行then中的回调
setTimeout(() => {
resolve('success')
}, 3000)
});
p1.then(
res => {
console.log(res),
err => console.log(err);
}).then(res => console.log(res,'rrr'))
Promise.all
// promise.all的实现
function myPromiseAll(promiseList) {
return new MyPromise((resolve, reject) => {
const result = [];
const count = 0;
const addData = (index,data) => {
result[index] = data;
count++
if(count === promiseList.length){
resolve(result)
}
}
promiseList.forEach((promise, index) => {
if (promise instanceof MyPromise) {
promise.then(
res => addData(index, res)
, err => reject(err)
)
}else{
addData(index, promise)
}
})
})
}
promise.race的实现
// promise.race的实现
function myPromiseAll(promiseList) {
return new MyPromise((resolve, reject) => {
promiseList.forEach((promise, index) => {
if (promise instanceof MyPromise) {
promise.then(
res => resolve(res)
, err => reject(err)
)
} else {
resolve(promise)
}
})
})
}
promise allSettled
function myPromiseAll(promiseList) {
return new MyPromise((resolve, reject) => {
const result = [];
const count = 0;
const addData = (index, data, status) => {
result[index] = {
data,
status
}
count++
if (count === promiseList.length) {
resolve(result)
}
}
promiseList.forEach((promise, index) => {
if (promise instanceof MyPromise) {
promise.then(
res => addData(index, res, 'fulfilled')
, err => reject(err,'rejected')
)
} else {
addData(index, promise,'fulfilled')
}
})
})
}
promise any
function myPromiseAll(promiseList) {
return new MyPromise((resolve, reject) => {
const count = 0;
promiseList.forEach(promise => {
promise.then(res => resolve(res),err => {
count++;
if (count === promiseList.length) {
reject(result)
}
})
})
})
}