promise是什么?
1、主要用于异步计算
2、可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
3、可以在对象之间传递和操作promise,帮助我们处理队列
promise是一个对象,对象和函数的区别就是对象可以保存状态,函数不可以(闭包除外)
并未剥夺函数return的能力,因此无需层层传递callback,进行回调获取数据
代码风格,容易理解,便于维护
多个异步等待合并便于解决
使用介绍
new Promise(
function (resolve, reject) {
// 一段耗时的异步操作
resolve('成功') // 数据处理完成
// reject('失败') // 数据处理出错
}
).then(
(res) => {console.log(res)}, // 成功
(err) => {console.log(err)} // 失败
resolve作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
promise有三个状态:
1、pending[待定]初始状态
2、fulfilled[实现]操作成功
3、rejected[被否决]操作失败
当promise状态发生改变,就会触发then()里的响应函数处理后续步骤;
promise状态一经改变,不会再变。
Promise对象的状态改变,只有两种可能:
从pending变为fulfilled
从pending变为rejected。
这两种情况只要发生,状态就凝固了,不会再变了。
1 JS
class KPromise {
// handle => function (resolve, reject) {
// // 一段耗时的异步操作
// resolve('成功') // 数据处理完成
// // reject('失败') // 数据处理出错
// }
constructor(handle) {
this.status = "pending";
this.value = undefined;
this.resolvedQueue = [];
this.rejectedQueue = [];
handle(this._resolve.bind(this), this._reject.bind(this));
}
_resolve(val) {
// console.log(this);
// 改变状态及value
this.status = "resolved";
this.value = val;
// console.log(val);
// 执行then里成功成功的回调
// console.log(this.resolvedQueue.length);
let run = ()=>{
let cb;
while(cb=this.resolvedQueue.shift()){
cb(val);
}
}
// setTimeout(run, 0);
let observer = new MutationObserver(run)
observer.observe(document.body,{
attributes: true
})
document.body.setAttribute("kkb",Math.random());
}
_reject(err) {
this.status = "rejected";
this.value = err;
// console.log(err);
// 执行then里失败的回调;
let run = ()=>{
let cb;
while(cb=this.rejectedQueue.shift()){
cb(err);
}
}
// setTimeout(run, 0);
// 模拟微任务;
let observer = new MutationObserver(run)
observer.observe(document.body,{
attributes: true
})
document.body.setAttribute("kkb",Math.random());
}
then(onResolved, onRejected) {
// 把多个 onResolved 及 onRejected 放在队列里;
// if (this.status === "resolved") {
// onResolved(this.value);
// } else if (this.status === 'rejected') {
// onRejected(this.value);
// }
// 加入队列, 没有执行;
// this.resolvedQueue.push(onResolved);
// this.rejectedQueue.push(onRejected);
// 返还KPromise对象;
return new KPromise((resolve,reject)=>{
// 在then里执行的回调
// let res = onResolved()
this.resolvedQueue.push(val=>{
val = onResolved && onResolved(val)
// val 111 、new KPromise();
if(val instanceof KPromise){
// console.log("promise...",val)
// 返还的KPromise对象;
return val.then(resolve);
}
// 返还的普通值;
resolve(val);
})
this.rejectedQueue.push(err=>{
onRejected && onRejected(err);
reject(err);
})
// if(res instanceof KPromise){
// console.log("then返还的是KPromise对象那个 ");
// }
// resolve(res);
})
}
static resolve(val){
return new KPromise(resolve=>{
resolve(val);
})
}
static reject(val){
return new KPromise((resolve,reject)=>{
reject(val);
})
}
static all(lists){
return new KPromise((resolve,reject)=>{
let arr = [];
for(let i=0;i<lists.length;i++){
lists[i].then(res=>{
arr.push(res);
},err=>{
reject(err);
throw Error("error..")
})
}
resolve(arr);
})
}
static race(lists){
return new KPromise((resolve,reject)=>{
for(let i=0;i<lists.length;i++){
lists[i].then(res=>{
resolve(res)
},err=>{
reject(err);
})
}
})
}
catch(onRejected){
this.then(undefined,onRejected);
}
}
promise.allSettled()
方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。
只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束。
每个成员对应一个传入Promise.allSettled()的 Promise 实例 ,一旦结束,状态总是fulfilled,不会变成rejected
使用eg:
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected]);
allSettledPromise.then(function (results) {
console.log(results);
});
// [
// { status: 'fulfilled', value: 42 },
// { status: 'rejected', reason: -1 }
// ]
static allSettled(lists){
return new KPromise((resolve,reject)=>{
let arr = [];
for(let i=0;i<lists.length;i++){
lists[i].then(res=>{
arr.push(res);
})
}
resolve(arr);
})
}
1 html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./myPromise.js"></script>
</head>
<body>
<h1>自己封装的promise</h1>
</body>
<script>
// setTimeout(() => {
// console.log("settimeout....");
// }, 0);
// let p = new KPromise((resolve,reject)=>{
// // resolve();
// // 执行了回调
// // setTimeout(() => {
// // resolve("success");
// // }, 100);
// reject("err");
// })
// console.log(p);
// then 加入队列 ;先执行 后加入了; --->先加入队列,后执行;
// let res = p.then(res=>{
// console.log(res);
// // console.log(res);
// // return KPromise
// // return 111;
// // return new KPromise(resolve=>{
// // resolve("返还的KPromise");
// // })
// },err=>{
// console.log(err);
// })
// console.log("??",res);
// then始终返还的promise对象;--->链式调用;
// res.then(res=>{
// console.log(res);
// })
// let p = KPromise.reject("111");
// console.log(p);
// let p = new KPromise((resolve,reject)=>{
// reject("err...");
// })
// p.then(res=>{
// console.log(res);
// }).catch(err=>{
// console.log(err);
// })
// let p1 = new KPromise((resolve,reject)=>{
// // resolve(111);
// reject("err...")
// })
// let p2 = new KPromise(resolve=>{
// resolve(222);
// })
// KPromise.all([p1,p2]).then(res=>{
// console.log(res);
// })
let p1 = new KPromise(resolve=>{
setTimeout(() => {
resolve(111);
}, 1000);
})
let p2 = new KPromise(resolve=>{
setTimeout(() => {
resolve(222);
}, 2000);
})
// 所有结果都必须是resolve;
// Promise.all([p1,p2]).then(res=>{
// console.log(res);
// })
KPromise.race([p1,p2]).then(res=>{
console.log(res);
})
</script>
</html>