Promise是啥玩意
Promise
是异步编程的一种解决方案,他的出现主要是解决异步事件回调地狱的问题。
何谓Promise
,简单说就是一个容器,里面保存着某个未来才会结束的事件,也就是一个异步操作,从语法上说,Promise
是一个对象,他可以获取异步操作的结果。并且提供统一的 API
可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
Promise优缺点
优点:我们通过上面的介绍已经了解到了,他可以将异步操作的流程以同步操作的的流程表达出来,把一层层嵌套的 callback 变成 .then().then()...
,从而使代码编写和阅读更直观,解决了异步操作回调嵌套的问题。
缺点:首先,无法取消Promise
,一旦新建它就会立即执行
,无法中途取消。其次,如果不设置回调函数,Promise
内部抛出的错误,不会反应到外部。第三,当处于pending
状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
基本用法
ES6 规定,Promise
对象是一个构造函数,用来生成Promise
实例。
Promise
构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
一个 Promise 实例有这几个状态
- pending:未确定状态。刚
new
出来的 Promise 处于这个状态;然后会马上执行 executor 中定义的语句 - resolved:代码执行到
resolve()
语句后 - rejected:代码执行到
reject()
语句后 - settled:resolved 或者 rejected 状态都属于 settled
resolve
函数的作用是,将Promise
对象的状态从“等待中”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject
函数的作用是,将Promise
对象的状态从“等待中”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
Promise
实例生成以后,可以用then
和catch
方法分别指定resolved
状态和rejected
状态的回调函数。
简单实现
- promise是个构造函数
- promise内部定义三个属性值 state状态 (初始状态pending,一经改变,无法更改), 成功返回值value,错误返回值reason
- promise接受一个函数作为参数,函数含有俩个参数resolve、reject, 这两个方法用来改变promise状态
- 初始化实例时 会立即执行处理器exector
- 所有promise实例都有then方法,所以then一定是在promise原型上
- then方法接受俩参数,成功回调,失败回调,如果是方法则执行
- promise内部要处理异步需要定义俩个数组
- 在then的时候如果promise是pending状态把回调方法放到数组里,在resolve或者reject时候调用
promise接收同步请求的结果(1-6毛皮)
// 1. pomise是个构造函数
function Promise(exector) {}
// 2. promise内部定义三个属性值 state状态 (初始状态pending,一经改变,无法更改), 成功返回值value,错误返回值reason
function Promise(exector) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
}
// 3. promise接受一个函数作为参数,函数含有俩个参数resolve、reject, 这两个方法用来改变promise状态
let p = new Promise((resolve, reject) => {
resolve('前端小菜鸟');
})
p.then(data => console.log(data)) // 前端小菜鸟
// 4. 初始化实例时 会立即执行处理器exector
function Promise(exector) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
exector(resolve,reject);
// 执行器其实就是promise接受的函数
// 立即执行
// (resolve, reject) => {
// resolve('前端小菜鸟');
// }()
function resolve(value) {
if(that.state === 'pending') {
that.value = value;
that.state = 'resolved';
}
}
function reject(reason) {
if(that.state === 'pending') {
that.reason = reason;
that.state = 'rejected';
}
}
}
// 初始化实例 执行器立即执行
let p = new Promise((resolve, reject) => {
resolve('前端小菜鸟');
})
p.then(data => console.log(data)) // 前端小菜鸟
// 5. 所有promise实例都有then方法,所以then一定是在promise原型上
// 6. then方法接受俩参数,成功回调,失败回调,如果是方法则执行
Promise.prototype.then = function (onFulfilled, onRejected) {
// then 方法有俩个回调函数 成功、失败
if(this.state === 'resolved'){ // resolved状态
if(typeof(onFulfilled) === 'function'){
onFulfilled(this.value);
}
}
if(this.state === 'rejected'){ // rejected状态
if(typeof(onRejected) === 'function'){
onRejected(this.reason);
}
}
}
promise接收异步请求的结果(7-8精髓)
// 7. promise内部要处理异步需要定义俩个数组
// 8. 在then的时候如果promise是pending状态把回调方法放到数组里,在resolve或者reject时候调用
function Promise(exector) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = []; // 异步成功回调
this.onRejectedCallbacks = []; // 异步失败回调
let that = this;
try{
// promise初始化实例时 会立即执行处理器exector
exector(resolve,reject);
// 执行器其实就是promise接受的函数
// (resolve, reject) => {
// resolve('前端小菜鸟');
// }()
}catch(err) {
console.log(err);
}
function resolve(value) {
if(that.state === 'pending') {
that.value = value;
that.onResolvedCallbacks.forEach((cb) => cb(value)); // resolve时候执行回调
that.state = 'resolved';
}
}
function reject(reason) {
if(that.state === 'pending') {
that.reason = reason;
that.onRejectedCallbacks.forEach((cb) => cb(reason)); // reject时候执行回调
that.state = 'rejected';
}
}
}
Promise.prototype.then = function (onFulfilled, onRejected) {
// then 方法有俩个回调函数 成功、失败
// pending状态的处理
if(this.state === 'pending') {
if(typeof(onFulfilled) === 'function'){
this.onResolvedCallbacks.push(onFulfilled);
}
if(typeof(onRejected) === 'function'){
this.onRejectedCallbacks.push(onRejected);
}
}
// resolved状态
if(this.state === 'resolved'){
if(typeof(onFulfilled) === 'function'){
onFulfilled(this.value);
}
}
// rejected状态
if(this.state === 'rejected'){
if(typeof(onRejected) === 'function'){
onRejected(this.reason);
}
}
}
// promise对象 接受一个函数作为参数,函数中包含俩参数resolve和reject标识成功和失败
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('前端大大大菜鸟');
},1000)
})
p.then(data => console.log(data)) // 前端大大大菜鸟
用class实现
class Promise1 {
// 实例属性和方法
constructor(executor) {
let that = this;
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = []; // 异步成功回调
this.onRejectedCallbacks = []; // 异步失败回调
executor(resolve, reject)
function resolve(val) {
if(that.state === 'pending') {
that.value = val;
that.onResolvedCallbacks.forEach(cb => {
cb(val);
})
that.state = 'resolved';
}
}
function reject(err) {
if(that.state === 'pending') {
that.reason = err;
that.onRejectedCallbacks.forEach(cb => {
cb(err);
})
that.state = 'rejected';
}
}
}
// 原型方法
then(onFulfilled, onRejected) {
if(this.state === 'pending') {
if(typeof(onFulfilled) === 'function'){
this.onResolvedCallbacks.push(onFulfilled);
}
if(typeof(onRejected) === 'function'){
this.onRejectedCallbacks.push(onRejected);
}
}
if(this.state === 'resolved' && typeof(onFulfilled) === 'function') {
onFulfilled(this.value);
}
if(this.state === 'rejected' && typeof(onRejected) === 'function') {
onFulfilled(this.value);
}
}
}
let p = new Promise1((resolve, reject)=>{
setTimeout(() => {
resolve('前端大菜鸟');
}, 10);
})
p.then(res=> {
console.log(res); // 前端大菜鸟
},err=>{
console.log(err);
})
结语
本篇文章只是介绍一下Promise、优缺点以及Promise的简单实现原理,promise的链式调用和其他方法会在后续更新。如有写的不对的地方请大佬指点我会第一时间改正。