为什么要用Promise
- 支持链式调用,可以解决回调地狱的问题
- 指定回调函数的方式更灵活 (启动异步任务,返回promise对象)
promise的状态改变
1.pending变为resolved
2.pending变为rejected
Promise构造函数
promise(excutor){ } //executor会在promise内部立即同步调用,异步函数在执行器中执行
改变Promise状态的三种方式
1.resolved( ‘ok’ ) 对应将pending—>fulfiled(resolved)
2.reject(‘err’) 对应pending–>rejected
3.抛出错误 throw ‘出问题’ —>rejected
改变状态和执行回调的顺序问题
1,如果Promise对象是同步时,执行回调里面的resolved或者reject然后执行then及相对于的回调
2,如果Promise对象是异步时,则先执行then,异步执行完了,先改变状态,再执行then里面的回调
Promise.then( )返回的新promise的结果状态由什么决定
1.如果抛出异常 throw 则新的promise变为rejectd,reason为抛出的异常
2.如果返回的是非Promise的任意值,新promise变为resolved,value为返回的值
3.如果返回的是另一个新的promise,此promise就会成为新promise的结果
中断Promise链的方法
p.then(value=>{
console.log(111)
return new Promise(()=>{}) //有且只有这种方法可以中断 因为pending的状态没有确定,就无法执行后续的回调函数
}).then().then()
Promise函数
//封装Promise函数
class Promise {
constructor(executor) {
//声明构造函数
this.PromiseState = 'pending';
this.PromiseResult = null;
//声明一个回调变量
this.callbacks = [];
const self = this;
function resolve(data) {
//判断状态 promise的状态对象只能改变一次
if (self.PromiseState !== 'pending') return;
//1.修改对象的状态
self.PromiseState = 'fulfilled';
//2.设置对象结果的值
self.PromiseResult = data;
//3.在此调用异步成功的回调函数
setTimeout(() => {
self.callbacks.forEach(item => {
item.onResolved(data)
})
})
}
function reject(data) {
//判断状态
if (self.PromiseState !== 'pending') return;
//1.修改对象的状态
self.PromiseState = 'rejected';
//2.设置对象结果的值
self.PromiseResult = data;
//3.在此调用异步成功的回调函数
setTimeout(() => {
self.callbacks.forEach(item => {
item.onRejected(data)
})
})
}
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
//添加then方法
then(onResolved, onRejected) {
const self = this;
//判断回调函数参数
if (typeof onResolved !== 'function') {
onResolved = value => value
}
if (typeof onRejected !== 'function') {
onRejected = reason => { throw reason }
}
//then方法执行回调
//通过PromiseState来判断执行then后的哪个回调函数
return new Promise((resolve, reject) => {
//封装函数
function callback(type) {
try { //传入的参数就是PromiseResult
let result = type(self.PromiseResult)
if (result instanceof Promise) {
//如果返回的结果是Promise对象
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
//非Promise
resolve(result)
}
} catch (e) {
reject(e)
}
}
if (this.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
})
}
if (this.PromiseState === 'rejected') {
setTimeout(() => {
callback(onResolved)
})
}
//判段pending的状态
if (this.PromiseState = 'pending') {
//保存回调函数 指定多个回调的实现
this.callbacks.push({
onResolved: function() {
callback(onResolved)
},
onRejected: function() {
callback(onRejected)
}
})
}
})
}
//添加catch方法
catch (onRejected) {
return this.then(undefined, onRejected)
}
//添加resolve方法 用static声明静态对象
static resolve(value) {
//返回promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v);
}, r => {
reject(r)
})
} else {
resolve(value)
}
})
}
//添加reject方法
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
//添加all方法
static all(promises) {
//返回结果是promise对象
return new Promise((resolve, reject) => {
//声明变量
let count = 0;
let arr = [];
//遍历
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
//得知对象的状态是成功的
//每个promise对象都成功
count++;
arr[i] = v;
if (count == promises.length) {
resolve(arr)
}
}, r => {
reject(r)
})
}
})
}
//添加race方法
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; i++) {
promises[i].then(v => {
//修改返回对象的状态 【成功】
resolve(v);
}, r => {
//修改返回对象的状态 【失败】
reject(r)
})
}
})
}
}