概念
抽象表达
- promise是用来解决异步编程(callback)回调地狱(callback hell)的一个解决方案
具体表达
- 从语法上来说:promise 是一个构造函数
- 从功能上来说:promise 是对象封装了一个异步操作并且能获取到其结果
状态
Promise 三种状态
- pending
- fulfilled
- rejected
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数
基础api
//new Promise 实例
const p = new Promise((resolve, reject) => {
//开始执行异步操作
setTimeout(() => {
//获取当前时间
let time = Date.now();
//判断偶数
if(time%2 === 1) {
resolve('成功的回调',time)
} else {
reject('失败的回调',time)
}
}, 0)
})
//通过.then 来指示成功和失败的结果
p.then(
value => {
console.log(value,'成功的数据')
},
reason => {
console.log(reason,'失败的数据')
}
)
常用方法
- then
- catch
- finallyall 静态方法
- race 静态方法
- any 静态方法
- resolve 静态方法
- reject 静态方法
all
Promise.all([p1,p2,p…])
接收一个由promise组成的数组,成功将返回所有promise成功的结果,有一个状态是reject将执行catch
race
Promise.race([p1,p2,p…])
接收一个由promise组成的数组,有一个promise状态是resolve,那么就返回第一个状态是resolve的promise的结果
为什么使用Promise
1、指定回调函数的方式更加灵活
- 旧的:必须在启动异步任务前指定
- promise:启动异步任务 => 返回promise 对象 => 给promise 对象绑定回调函数(甚至可以异步任务结束后指定/多个)
2、支持链式调用,可以解决回调地狱问题
- 什么是回调地狱 ? 回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调函数执行的条件
- 回调地狱的缺点 ? 不便于阅读 / 不便于异常处
- 理解决方案 ? promise 链式调用
- 终极解决方案 ?async/await
ES6 - Promise 实现原理
global.Promise = (function () {
class Promise {
constructor(callback) {
this.val = undefined;
this.status = "pending";
this.init(callback);
}
onReject = err => {
this.val = err;
this.status = "reject";
console.log("onReject is call");
};
onResolve = val => {
this.val = val;
this.status = "fulfilled";
console.log("onResolve is call");
};
init(callback) {
callback(this.onResolve, this.onReject);
}
then(resolve, reject) {
if (this.status === "fulfilled") {
resolve(this.val);
} else if (this.status === "reject") {
if (!reject === undefined) reject(this.val);
}
return this;
}
finally(cb) {
if (this.status === "fulfilled" || this.status === "reject") {
cb();
}
}
catch(cb) {
cb(this.val);
return this;
}
}
Promise.reject = function () {};
Promise.resolve = function () {};
return Promise;
})();
function getApi(flag = true) {
return new Promise((resolve, reject) => {
if (flag) {
resolve(123);
} else {
reject(new Error("你错了!"));
}
});
}
getApi(true)
.then(res => {
console.log(res);
return 123;
})
.then(val => {
console.log(val);
})