node 异步编程Promise容器

本文详细介绍了ES6中的Promise概念及其工作原理,包括Promise的基本用法、状态转换特性及如何通过实现简单的Promise来解决异步编程的问题。

Promise介绍

Promise是ES语言标准里面提供的一种异步编程解决方案,promise相当于一个容器,promise容器的状态只有两种,完成状态,失败状态 ;容器的状态一旦改变就不可逆。
框架构成:promise是高级接口,事件模块events是低级模块并提供基础性支持

promise提案有很多种模型,CommonJS目前已经了Promises/A、Promises/B、Promises/D
下面以promiseA作说明:

  1. 一个promise只需提供一个then()方法,接受完成,错误状态的回调方法;当出现错误,或者状态完成时调用相应的方法。
  2. 可选的支持progress事件回调作为第三个方法。
  3. then方法只接受function对象,其余对象均会忽略。
  4. then方法继续返回promise对象,以便实现链式调用
  5. then方法的定义:then(fulfilledHandler, errorHandler, progressHandler)

    promiseA模型简单模仿:

var Promise = function () {
EventEmitter.call(this);
};
util.inherits(Promise, EventEmitter);
Promise.prototype.then = function (fulfilledHandler, errorHandler, progressHandler) {
if (typeof fulfilledHandler === 'function') {
//利用once方法只会执行一次,这就保证了promise的状态一旦定了就不会改变
this.once('success', fulfilledHandler);
}
if (typeof errorHandler === 'function') {
//利用once方法只会执行一次
this.once('error', errorHandler);
}
if (typeof progressHandler === 'function') {
、//progress可以多次触发,保证可以链式调用(可以一直触发progress事件)
this.on('progress', progressHandler);
}
return this;
};
//Deferred 延迟对象
var Deferred = function () {
this.state = 'unfulfilled';
this.promise = new Promise();
};
Deferred.prototype.resolve = function (obj) {
this.state = 'fulfilled';
this.promise.emit('success', obj);
};
Deferred.prototype.reject = function (err) {
this.state = 'failed';
this.promise.emit('error', err);
};
Deferred.prototype.progress = function (data) {
this.promise.emit('progress', data);
};

Promise封装实现异步编程

支持序列执行的promise封装
var fs=require('fs');
var Deferred=function () {
    this.promise=new Promise();
};

Deferred.prototype.resovle=function (obj) {
    var promise=this.promise;
    var handler;
    while (handler=promise.queue.shift()){
        if (handler && handler.fulfilled){
            var ret=handler.fulfilled(obj);
            if (ret && ret.isPromise){
                ret.queue=promise.queue;
                this.promise=ret;
                return;
            }
        }
    }
};

Deferred.prototype.reject=function (err) {
    var promise=this.promise;
    var handler;
    while (handler=promise.queue.shift()){
        if (handler && handler.error){
            var ret=handler.error(err);
            if (ret && ret.isPromise){
                ret.queue=promise.queue;
                this.promise=ret;
                return;
            }
        }
    }
};

//生成回调函数
Deferred.prototype.callback=function () {
    var that=this;
    return function (err,file) {
        if (err) {
            return that.reject(err);
        }
        that.resovle(file);
    }
};

var Promise=function () {
    //队列用来存储待执行的回调函数
    this.queue=[];
    this.isPromise=true;
};

Promise.prototype.then=function (fulfilledHandler,errorHandler,progressHandler) {
    var handler={};
    if (typeof fulfilledHandler ==="function"){
        handler.fulfilled=fulfilledHandler;
    }
    if (typeof errorHandler ==="function"){
        handler.error=errorHandler;
    }
    this.queue.push(handler);
    return this;
};

var readFile1=function (file,encoding) {
    var deferred=new Deferred();
    fs.readFile(file,encoding,deferred.callback);
    return deferred.promise;
};
var readFile2=function (file,encoding) {
    var deferred=new Deferred();
    fs.readFile(file,encoding,deferred.callback);
    return deferred.promise;
};

readFile1('file1.txt','utf-8').then(function (file1) {
    return readFile2(file1.trim(),'utf-8');
}).then(function (file2) {
    console.log(file2);
});

//继续优化
var smoth=function (method) {
    return function () {
        var deffed=new Deferred();
        var args=Array.prototype.slice.call(arguments,0);
        args.push(deffed.callback());
        method.apply(null,args);
        return deffed.promise;
    }
};

var readFile1_=function (file,encoding) {
    var deffred=new Deferred();
    fs.readFile(file,encoding,deffred.callback());
    return deffred.promise;
};

var readFile2_=function (file,encoding) {
    var deffred=new Deferred();
    fs.readFile(file,encoding,deffred.callback());
    return deffred.promise;
};

// var readFile=smoth(fs.readFile);
//要实现同样的效果,代码将会减少到
var readFile=smoth(fs.readFile);
readFile('file1.txt','utf-8').then(function (file1) {
    return readFile(file1.trim(),'utf-8');
}).then(function (file2) {
    console.log(file2);
});

**上面介绍的promise示范代码均为理解promiSee提案,在实际代码中请使用比较成熟的promise实现;when模块,或者q模块 可以使用npm install when/q**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值