promise模式

为什么使用promise

回调表达式程序异步和管理并发的两个缺陷,缺乏顺序性和可信性,如下:

1>nodejs异步读取文件,异步函数:

var fs = require('fs');
function readJSON(filename,callback){
    fs.readFile(filename,'utf8',function(err,res){
        if(err){
            return callback(err,null);
        }
        try{
            var res = JSON.parse(res);
        }catch(ex){
            callback(ex)
        }
        callback(null,res);
    });
}
异步文件必须包含两个参数,文件名和回调函数,上诉调用函数时候不知道callback的参数,还有就是多个嵌套

2>异步函数调用

fs.readFile('file1.txt','utf8',function(err,res){
    fs.readFile('file2.txt','utf8',function(err,res){
        fs.readFile('file2.txt','utf8',function(err,res){
            console.log(res);
        });
    });
});

通过第三方提供给我们任务结束的能力,而不是等待第三方提供数据,最后使用自己的代码决定下一步干啥


2.定义

promise代表必须异步处理的函数返回的值或者异常,promise将异步对象与回调函数脱离,then异步操作上绑定回调函数

1》三种状态:pending,fulfilled,rejected

2》promise唯一的接口then,支持链式调用

function sendXHR(resolve, reject){
    var xhr = new XMLHttpRequest();
    xhr.open('get', 'QueryUser', true);
    xhr.onload = function(){
        if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){
            resolve(xhr.responseText);
        }else{
            reject(new Error(xhr.statusText));
        }
    };
    xhr.onerror = function(){
        reject(new Error(xhr.statusText));
    }
    xhr.send(null)
}

3.实现

1>实现异步对象状态与回调函数剥离,还能使用回调函数正常执行

2>链式调用与管理状态的实现

//使用then方法添加回调函数,把这次回调函数return的结果当做return的promise的resolve的参数
Promise.prototype.then = function(onResolved, onRejected){
    var self = this;
    return new Promise(function(resolve, reject){
        var onResolvedFade = function(val){
            var ret = onResolved?onResolved(val):val;//这一步主要是then方法中传入的成功回调函数通过return来进行链式传递结果参数
            if(Promise.isPromise(ret)){//回调函数返回值也是promise的时候
                ret.then(function(val){
                    resolve(val);
                });
            }
            else{
                resolve(ret);
            }
        };
        var onRejectedFade = function(val){
            var ret = onRejected?onRejected(val):val;
            reject(ret);
        };
        self.handlers.push(onResolvedFade);
        if(self._status === FULFILLED){
            onResolvedFade(self._value);
        }

        if(self._status === REJECTED){
            onRejectedFade(self._value);
        }
    });
}

onResolved, onRejected默认为函数
onFulfilled: 在promise已完成后调用且仅调用一次该方法,该方法接受promise最终值作参数
onRejected: 在promise被拒绝后调用且仅调用一次该方法,该方法接受promise拒绝原因作参数;两个函数都是异步事件的回调,符合JavaScript事件循环处理流程
该方法必须返回一个promise:varpromise2=promise1.then(onFulfilled,onRejected);

通过上面的代码可以看出,前面提出的2个问题得到了解决:

1.在promise对象中有3个属性,state,value,handlers,这3个属性解决了状态和回调的脱离,并且在调用then方法的时候才将回调函数push到handlers属性上面(此时state就是1,可以在后面的代码中执行onResolve)

2.链式调用通过在then方法中返回的promise对象实现,并且通过onResolvedFade将上一个回调的返回值当做这次的result参数来执行进行传递。


4.resolution决议过程

一个promise和一个值[[result]](promise,x),其中x为promise,promise就直接使用x的状态,若x为对象或者函数,获取x.then的引用,若抛出异常则是拒绝promise,否则会引用赋值给then,若then为函数,就调用传递两个回调函数参数(resolvePromise,rejectPromise)


5.es6中的promise  javascript支持Promise,浏览器chrome也支持该功能)

 var promise = new Promise((resolve, reject) => {
        setTimeout(function() {
            resolve('完成');
        }, 10);
    });
    promise.then((msg) => {
        console.log('first messaeg: ' + msg);
    })
    promise.then((msg) => {
console.log('second messaeg: ' + msg);
    });

输出如下:

5-1.  promise模式:构造器   newPromise(function(resolve,reject){});

实例化时,会初始一个异步任务,在异步任务完成或失败时,调用resolve或reject函数来完成或拒绝返回的Promise对象。另外需要注意的是,若传入的函数执行抛出异常,那么这个promsie将被拒绝

5-2.  promise模式:静态方法  Promise.all([...iterable])

all方法接受一个或多个promsie(以数组方式传递),返回一个新promise,该promise状态取决于传入的参数中的所有promsie的状态:

var p1 = new Promise((resolve, reject) => {
        setTimeout(function(){
            console.log('p1决议');
            resolve('p1');
        }, 10);
    });
    var p2 = new Promise((resolve, reject) => {
        setTimeout(function(){
            console.log('p2决议');
            resolve('p2');
        }, 10);
    });
    Promise.all( [p1, p2] )
    .then((msgs) => {
        // p1和p2完成并传入最终值
        console.log(JSON.stringify(msgs));
    })
    .then((msg) => {
        console.log( msg );
    });


5-3.  promise模式:Promise.race(iterable)

     race方法返回一个promise,只要传入的诸多promise中的某一个完成或被拒绝,则该promise同样完成或被拒绝,最终值或拒绝原因也与之相同。

Promise.resolve(x)

resolve方法返回一个已决议的Promsie对象:

  1. 若x是一个promise或thenable对象,则返回的promise对象状态同x;
  2. 若x不是对象或函数,则返回的promise对象以该值为完成最终值;
  3. 否则,详细过程依然按前文Promsies/A+规范中提到的规则进行。

该方法遵循Promise/A+决议规范。

5-4.  promise模式:Promsie.reject(reason)

        返回一个使用传入的原因拒绝的Promise对象。

5-5.举实例

        对比回调函数与promise实现x和y相加,等到俩个值完全执行好后,执行相加运算

1>回调函数实现

function add(getx,gety,cb){

var x,y;

getx({function(xVal){

x=xval;

if(y!=undefined)cb(x+y)

}})

gety({function(xVal){

y=yval;

if(x!=undefined)cb(x+y)

}})


}

add(fetchx,fetchy,function(sum){console.log(sum)})

2>利用promise实现

function add(xp,yp){

return Promise.all([xp,yp]);                        //调用并创建一个promise来等待xp,yp决议

.then(function(values){return values[0]+values[1]});    //等待.all的promise

}

add(fetchx(),fetchy())   //直接调用返回值(promise),可能未就绪

.then(function(sum){console.log(sum)},function(err){console.log(err)});


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值