ES6 Promise原理

ES6 Promise原理

  • 一、Promise是什么
  • 二、为什么会有Promise
    • 1、回调地狱 + 异步同步事件调用顺序带来的双重伤害
    • 2、回调事件的分离
  • 三、Promise的三种状态
    • 1、resolve
    • 2、reject
    • 3、pending
  • 四、then catch all race
    • 1、then
    • 2、catch
    • 3、all
    • 4、race
  • 五、基本用法
  • 六、实现Promise

一、Promise是什么

A promise is an object that may produce a singe value some time in the future:either a resolved value ,or a reason that it’s not resolved .(e.g.,a network error occurred)
简单说就是一个异步实现的对象,它或者可以解决掉问题,或者可以给予一个未能解决掉这个问题的原因。

二、为什么会有Promise

1、回调地狱 + 异步同步事件调用顺序带来的双重伤害

promise是一个异步函数,并且它能够解决地狱回调。地狱回调简单理解为回调中嵌套回调,当回调的层数太多了就会看起来很混乱。当然如果promise的then太多了,那么我们可以使用Generator或async/await

2、回调事件的分离

then返回的是一个新的promise,它是通过之前的一个promise返回值的不同进行不同方法的调用。即如果上一个promise成功了就执行第一个方法,如果上一个未成功就执行第二个方法。

三、Promise的三种状态

1、resolve

将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;

2、reject

将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

3、pending

当前promise状态正在执行,状态只要改变,就会凝固不会再次变化,且方法只能被调用一次。

四、then catch all race

1、then

1、接收两个函数作为参数,分别代表resolve和rejected
2、.then()返回一个新的Promise实例,所以它可以链式调用
3、当前面的Promise状态改变时,.then()根据其最终状态,选择特定的状态响应函数执行
4、状态响应函数可以返回新的promise,或其他值,不返回值也可以我们可以认为它返回了一个null;
5、如果返回新的promise,那么下一级.then()会在新的promise状态改变之后执行
6、如果返回其他任何值,则会立即执行下一级.then()

2、catch

catch方法会捕捉catch前到上一个catch中间的,没有设置then的reject方法的reject.

	thing1()
	.then(()=>{
   		return thing2();   
    })
	.then(()=>{
      return thing3()
    })
	.catch((err)=>{
     	return err1() 
   })
	.then(()=>{
      return thing4()
    },(err)=>{
      return err2()
    })
	.catch((err)=>{
      return err3()
    })
	.then(()=>{
      return thing5()
    })

catch会捕获catch之前所有的未捕获的异常,并且返回一个resolved状态的promise实例。
catch和then的区别,catch会捕获之前所有的reject,而then只捕获之前的一个reject。

3、all

al将多个promise封装为一个新的promise,all接收一个数组作为参数,数组里可以是Promise对象,也可以是别的值,只有Promise会等待状态改变
当所有的子Promise都完成,该Promise完成,返回值是全部值的数组。
有任何一个失败,该Promise失败,返回值是第一个失败的子Promise结果

4、race

类似于all,区别在于它有任意一个完成就算完成

五、基本用法

// 第一步:model层的接口封装
            const promise = new Promise((resolve, reject) => {
                // 这里做异步任务(比如ajax 请求接口。这里暂时用定时器代替)
                setTimeout(function() {
                    var flag = 0 // 接口返回的数据
                    if (flag == 0) {
                        // 接口请求成功时调用
                        resolve(flag);
                    } else {
                        // 接口请求失败时调用
                        reject('network error');
                    }
                }, 0);
            });

            // 第二步:业务层的接口调用。这里的 data 就是 从 resolve 和 reject 传过来的,也就是从接口拿到的数据
            promise.then(data => {
                // 从 resolve 获取正常结果
                console.log(data);
            }).catch(data => {
                // 从 reject 获取异常结果
                console.log(data);
            });

六、实现Promise

因为promise是一个类,所以promise要用new方法去定义

//定义promise的三个状态
enum state = {
	penging:"pending",
	resolved = "resolved",
	rejected = "rejected"
}
class promise{
	constructor(callback) {
		callback(this._resolve.bind(this),this._reject.bind(this));
	}
	_state: state = state.pending;
	_value: any;
	_resolve(val) {
		if(this._state === state.pending){
			this._value = val;
			this._state = state.resolved;
			this._runResolveArray();
		}
	}
	
	_reject() {}
	_runResolveArray(){
		this._resArray.forEach(item =>{
			const result = item.handle(this._value);
			const nextPromise = item.promise;
			
			if(result instanceof promise){
				result.then(val=>item.promise._resolve(val))
			}else{
				item.promise.resolve(result)
			}
		})
	}
	_resArray = []
	
	then(onRes , onRej = () => {}) {
		const newPromise = new promise(() => {});
		const item = { promise: newPromise, handle: onRes};
		this._resArray.push(item)
		if(this._state === state.resolve){
			this._runResolveArray();
		}
		return newPromise;	
	}
}

注意:promise的方法是同步方法,then是微任务的异步代码。

你可能感兴趣的:(ES6,es6)