Promise的几个关键问题
- 如何改变promise的状态?
调用resolve就是成功,调用reject就是失败,还有一个抛出异常,然后当前是pending就会改变为rejected
const p = new Promise((resolve, reject) => {
throw new Error('出错了');
})
console.log(p);
-
一个promise指定多个成功/失败回调函数,都会调用吗?
都会调用 -
改变promise状态和指定回调函数谁先谁后?
都有可能,当执行器函数里面有定时器的时候,就是先指定回调函数再改变promise的状态,同理,把指定的回调函数放在定时器里面就可以正好反过来,想要先改变promise的状态还有一个简单的方法,就是将执行器函数里面的定时器删除,让他们直接进行同步执行 -
then返回的新promise的结果状态由什么决定?
由then回调函数的返回值决定,默认返回undefined,走的是resolve- 若抛出异常,新的promise状态为rejected,reason就是抛出的异常
- 若返回的是非promise的任意值,新promise变为resolved,value就是返回的值
- 如果返回的是另一个新的promise,这个promise的结果就是新的promise的结果
-
promise如何串联多个操作任务?
通过then的链式调用串联多个同步/异步任务,想要同步操作的话直接return,想要异步操作的话就返回promise -
promise异常传递
当使用promise的then的链式调用的时候,可以在最后指定失败的回调,前面任何操作出了异常,都会传到最后失败的回调中处理 -
中断promise链
当在链式调用的时候,如果想在中间中断,即不再调用后面的回调函数,解决办法是在回调函数中返回一个pending状态的promise对象,也就是返回一个空的promise
reason => {
throw reason;}//如果不写reason默认是将reason抛出
自定义promise
// 自定义Promise函数模块:IIFE
(function (window) {
// 常量一般用全大写来命名
const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
// excutor同步执行
function Promise(excutor) {
const self = this;
this.status = PENDING;
this.data = undefined;
this.callbacks = [];
function resolve(value) {
if (self.status !== PENDING) {
return ;
}
self.status = RESOLVED;//修改状态
self.data = value;//保存value
// 如果有待执行的callback函数,立即异步执行回调
if (self.callbacks.length > 0) {
setTimeout(() => {
//放入队列
self.callbacks.forEach(calobj => {
calobj.onResolved(value);
});
}, 0)
}
}
function reject(reason) {
if (self.status !== PENDING) {
return ;
}
self.status = REJECTED;//修改状态
self.data = reason;//保存value
// 如果有待执行的callback函数,立即异步执行回调
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(calobj => {
calobj.onRejected(reason);
});
}, 0)
}
}
try{
excutor(resolve, reject);
}catch(error){
reject(error);
}
}
// then
Promise.prototype.then = function (onResolved, onRejected) {
onResolved = typeof onResolved === 'function' ? onResolved : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => {
throw reason}//用于判断是否是异常传递
const self = this;
return new Promise((resolve, reject) => {
function handle(callback) {
// 三种情况,1. 抛出异常2. 返回非promise3. 返回promise
try {
const result = callback(self.data);
if (result instanceof Promise) {
// result.then(
// value => resolve(value),
// reason => reject(reason)
// )
result.then(resolve, reject);
}else{
resolve(result);
}
} catch (error) {
reject(error);
}
}
if (self.status === PENDING) {
self.callbacks.push(
{
onResolved(value) {
handle(onResolved);
},
onRejected(reason) {
handle(onRejected);
}}
)
}else if (self.status === RESOLVED) {
setTimeout(() => {
handle(onResolved);
}, 0)
}else{
setTimeout(() => {
handle(onRejected);
}, 0)
}
})
}
// catch
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected);
}
// resolve
Promise.resolve = function (value) {
// 根据value判断具体返回啥
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject);
}else{
//不是promise
resolve(value);
}
})
}
// reject
Promise.reject = function (reason) {
// 直接返回一个失败的promise
return new Promise((resolve, reject) => {
reject(reason);
})
}
// all
Promise.all = function (promises) {
const values = new Array(promises.length);
let count = 0;
return new Promise ((resolve, reject) => {
promises.forEach((p, index) => {
Promise.resolve(p).then(
value => {
count ++;
values[index] = value;
if (count == promises.length) {
resolve(values);
}
},
reason => {
reject(reason);
}
)
})
})
}
// race
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
promises.forEach((p, index) => {
Promise.resolve(p).then(
value => {
resolve(value);
},
reason => {
reject(reason);
}
)
})
})
}
Promise.resolveDelay = function (value, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (value instanceof Promise) {
value.then(resolve, reject);
}else{
//不是promise
resolve(value);
}
}, time)
})
}
Promise.rejectDelay = function (reason, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(reason);
}, time)
})
}
window.Promise = Promise;//向外暴露promise
})(window)
// 自定义Promise函数模块:IIFE
(function (window) {
// 常量一般用全大写来命名
const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
// excutor同步执行
class Promise {
constructor(excutor) {
const self = this;
this.status = PENDING;
this.data = undefined;
this.callbacks = [];
function resolve(value) {
if (self.status !== PENDING) {
return ;
}
self.status = RESOLVED;//修改状态
self.data = value;//保存value
// 如果有待执行的callback函数,立即异步执行回调
if (self.callbacks.length > 0) {
setTimeout(() => {
//放入队列
self.callbacks.forEach(calobj => {
calobj.onResolved(value);
});
}, 0)
}
}
function reject(reason) {
if (self.status !== PENDING) {
return ;
}
self.status = REJECTED;//修改状态
self.data = reason;//保存value
// 如果有待执行的callback函数,立即异步执行回调
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(calobj => {
calobj.onRejected(reason);
});
}, 0)
}
}
try{
excutor(resolve, reject);
}catch(error){
reject(error);
}
}
// then
then (onResolved, onRejected) {
onResolved = typeof onResolved === 'function' ? onResolved : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => {
throw reason}//用于判断是否是异常传递
const self = this;
return new Promise((resolve, reject) => {
function handle(callback) {
// 三种情况,1. 抛出异常2. 返回非promise3. 返回promise
try {
const result = callback(self.data);
if (result instanceof Promise) {
// result.then(
// value => resolve(value),
// reason => reject(reason)
// )
result.then(resolve, reject);
}else{
resolve(result);
}
} catch (error) {
reject(error);
}
}
if (self.status === PENDING) {
self.callbacks.push(
{
onResolved(value) {
handle(onResolved);
},
onRejected(reason) {
handle(onRejected);
}}
)
}else if (self.status === RESOLVED) {
setTimeout(() => {
handle(onResolved);
}, 0)
}else{
setTimeout(() => {
handle(onRejected);
}, 0)
}
})
}
// catch
catch (onRejected) {
return this.then(undefined, onRejected);
}
// resolve
static resolve (value) {
// 根据value判断具体返回啥
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject);
}else{
//不是promise
resolve(value);
}
})
}
// reject
static reject (reason) {
// 直接返回一个失败的promise
return new Promise((resolve, reject) => {
reject(reason);
})
}
// all
static all (promises) {
const values = new Array(promises.length);
let count = 0;
return new Promise ((resolve, reject) => {
promises.forEach((p, index) => {
Promise.resolve(p).then(
value => {
count ++;
values[index] = value;
if (count == promises.length) {
resolve(values);
}
},
reason => {
reject(reason);
}
)
})
})
}
// race
static race (promises) {
return new Promise((resolve, reject) => {
promises.forEach((p, index) => {
Promise.resolve(p).then(
value => {
resolve(value);
},
reason => {
reject(reason);
}
)
})
})
}
static resolveDelay (value, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (value instanceof Promise) {
value.then(resolve, reject);
}else{
//不是promise
resolve(value);
}
}, time)
})
}
static rejectDelay (reason, time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(reason);
}, time)
})
}
}
window.Promise = Promise;//向外暴露promise
})(window)