在JavaScript的世界中,所有代码都是单线程执行的。由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现,但是这样的做法往往让代码,与思维进入了回调地狱当中;
function after(times,callback){
return function(obj){
if(--times===0){
callback(obj)
}
}
}
在相当复杂的代码中如何回避回调地狱这种情况的,Promise模式也许是一个不错,可以使异步代码看起来如同步般清新易读,从而从回调地狱中解脱出来,ES6中 已原生支持 Promise,自然而然promise也有了他的一套规范;
rules
rules
- 1.new Promise时需要传递一个executor执行器,执行器会立刻执行
- 2.执行器中传递了两个参数 resolve成功的函数 他调用时可以传一个值 值可以是任何值 reject失败的函数 他调用时可以传一个值 值可以是任何值
- 3.只能从pending态转到成功或者失败
- 4.promise实例。每个实例都有一个then方法,这个方法传递两个参数,一个是成功另一个是失败
- 5.如果调用then时 发现已经成功了 会让成功函数执行并且把成功的内容当作参数传递到函数中
- 6.promise 中可以同一个实例then多次,如果状态是pengding 需要将函数存放起来 等待状态确定后 在依次将对应的函数执行 (发布订阅)
一个Promise存在三种状态
- pending: 初始状态
- resolve: 可以理解为成功
- reject: 可以理解为失败
Analysis Promise
首先我们来看原生如何调用Promise
new Promise((resolve,reject)=>{});
这里我们可以看出再调用构造函数时,其实传递了一个执行器
如果我们自己该怎样去实现这个流程.
rule.1
function Promise(executor){
<!--这里的构造器传递了两个匿名函数-->
function resolve(){
}
function reject(){
}
executor(resolve,reject)
}
我们再看看rule.2不论是失败还是成功的情况,都会传递一个值,再结合rule3,我们可以预先给定一个预状态
function Promise(executor){
let _this=this;
_this.status='pending';
_this.value='undefined';
_this.reason='undefined';
function resolve(value){
if( _this.status==='pending'){
_this.status='resolved';
_this.value=value;
}
}
function reject(reason){
if(_this.status==='pending'){
_this.status='rejected';
_this.value=value;
}
}
executor(resolve,reject)
}
接下来我们看看rule4,每一个promise实例,都应该有一个then方法并且可以传递两个参数,一个成功,一个失败,并且返回一个promise实例
function Promise(executor){...};
Promise.prototype.then=function(onfulfilled,onrejected){
//这里应该还应该处理为传递参数的情况
onfilfulled=typeof onfilfulled==='function?onfilfulled:val=>val;
onrejected=typeof onrejected==='function?onrejected:val=>{throw val};
let promise2=new Promise((resolve,reject)=>{
.......
})
return promise2
}
我们做个假设如果resolve是异步的,情况又该如何处理;我觉得应该先把存储起来,然后异步调用
function Promise(executor){
....
let _this=this;
_this.onResolves=[];
_this.onRejects=[];
...
_this.onRejects.forEach(fn=>fn())
...
...
_this.onResolves.forEach(fn=>fn())
....
}
如果我们的resolve是一个promise那么我们就还应该进一步解析,所以应该定义一个方法来处理这种情况
function resolvePromise(promise2, x, resolve, reject) {
......
}