Promise的简朴完成

ES6 原生供应了 Promise 对象,大大简化了 callback 的代码保护难度。运用promise对象以后能够运用一种链式挪用的体式格局来构造代码;让代码越发的直观。

假如想在老浏览器中运用 Promise,须要运用第三方库。现实完成阔别并不庞杂,仅须要十几行代码,就可以完成相似的效果(现实照样有点区分的)。

// 简朴的完成 Promise 的函数
// 原文地点:http://www.miaoqiyuan.cn/p/promise
var PromiseDemo = function(fun, _status_code){
    
    this._status_code = _status_code || 'status';
    
    //实行
    this.run = function(){
        this._result = fun.call(this, fun);
        
        //假如实行函数会 同步 返回效果,则挪用callback。
        if( !! this._result ){
            return this.callback();
        };
    };
    
    //回调函数,假如不是马上返回效果,须要手动挪用
    this.callback = function(_result){
        
        //异部挪用时,传入实行效果
        if( !!_result ){
            this._result = _result;
        }
        
        //如过状况不是 object
        this._result = this._result || {};
        
        //假如没有指定 【返回状况】 值,假如没有,则运用 status
        this._status = this._result[this._status_code] || 'fail';
        
        /*
            假如 【返回状况】 已定义了 回调函数,挪用本状况回调函数
            假如 【返回状况】 没有定义,则挪用 _default 函数
            假如 【返回状况】 没有定义,而且没有挪用 _default 函数,抛出非常
        */
        this._callback = this[this._status] || this._default || function(){ throw new Error("Undefined " + this._status); };
        return this._callback.call(this);
    };
    
    //then推断
    this.then = function(_status, callback){
        if( typeof _status == "function" ){
            
            //没有指定状况
            callback = _status;
            if( !('success' in this) ){
                
                //没有 success,则将 callback 设置为 success 状况的回调函数
                _status = 'success';
                
            }else if( !('fail' in this) ){
                
                //没有 fail,则将 callback 设置为 fail 状况的回调函数
                _status = 'fail';
                
            }else{
                
                // 假如 success 和 fail 已设置,不管挪用多少次,都是 默许状况 的回调函数
                _status = '_default';
                
            };
        };
        
        //设置 【返回状况】 的回调函数
        this[_status] = callback;
        
        //链式操纵
        return this;
    };
    
    //链式操纵
    return this;
}
就这么几行代码,就完成了简朴的 Promise。为了轻易测试,写成函数
var PromiseTest = function(fun, _status_code, _default){
    if( typeof _status_code == "function" ){
        _default = _status_code;
        _status_code = undefined;
    }
    var pTest = new PromiseDemo(fun, _status_code);
    
    pTest.then(function(){
        console.log("Success!");
        console.log(this._result);
    });
    
    pTest.then(function(){
        console.log("Fail!");
        console.log(this._result);
    });
    
    if( typeof _default == "function"){
        pTest.then(_default);
    };

    return pTest;
}
下面的代码用于测试效果:

返回胜利状况
PromiseTest(function(){
    return { status: 'success'};
}).run();
/*
    Success!
    Object {status: "success"}
*/
返回失利状况
PromiseTest(function(){
    return { status: 'fail'};
}).run();
/*
    Fail!
    Object {status: "fail"}
*/
返回其他状况,没有定义,抛出非常
PromiseTest(function(){
    return { status: 'other'};
}).run();
/*
    Uncaught Error: Undefined other(…)
*/
修正 【返回状况】 参数,返回胜利状况
PromiseTest(function(){
    return { status: 'other', code : 'success'};
}, "code").run();
/*
    Success!
    Object {status: "other", code: "success"}
*/
增添默许值函数,一切未定义的状况,都是用此回调函数
PromiseTest(function(){
    return { status: 'other'};
}, function(){
    console.log("Other");
}).run();
/*
    Other
*/
自定义状况值,返回 nicai 状况
PromiseTest(function(){
    return { status: 'nicai'};
}).then('wocai', function(){
    console.log("Wocai");
}).then('nicai', function(){
    console.log("Nicai");
}).run();
/*
    Nicai
*/
同步挪用有返回值
PromiseTest(function(){
    return { status: 'nicai', value : "abc"};
}).then('nicai', function(){
    console.log("Nicai");
    return this._result.value;
}).run() == 'abc';
/*
    Nicai
    true
*/
异部挪用测试:setTimeout
PromiseTest(function(){
    setTimeout(
        (function(){
            this.callback({
                status : 'success'
            });
        }).bind(this),    //必需bind,不然函数内部的 this == window
    1000);
}).run();
/*
    Success!
    Object {status: "success"}
*/
异部挪用测试:Ajax
PromiseTest(function(){
    $.ajax({
         type    : "POST",
        url        : "/services/PinYin",
        data    : {input:'测试'},
        success    : (function(result){
            this.callback({
                status : 'success',
                result : result
            });
        }).bind(this),    //经由过程 bind 转变 this 的指向
        error    : (function(){
            this.callback();
        }).bind(this)
    });
}).run();

//胜利
/*
    Success!
    Object {status: "success", result: "Ceshi"}
*/

//失利
/*
    Fail!
    Object {}
*/
异部挪用测试:假如须要用 this 接见 jQuery 的 ajax 对象
PromiseTest(function(){
    var me = this;    //在本函数内,用能够 me 指向 this(PromiseDemo的实例);
    $.ajax({
         type    : "POST",
        url        : "/services/PinYin",
        data    : {input:'测试'},
        success    : (function(result){
            me.callback({
                status : 'success',
                result : result
            });
        }),
        error    : (function(){
            me.callback();
        })
    });
}).run();
    原文作者:mqycn
    原文地址: https://segmentfault.com/a/1190000007235631
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞