由于项目开发需要解决JS同步的问题,但是受限在目前的框架里没有引用到jQuery,也就无法使用defered。也是自己嫌麻烦,于是开始重新造轮子的过程——服务于自己的测试代码,写了一个简易的promise的实现。

  • Promise 下面有个src/Promise.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    Promise.js
    /**
    * Created by turbineyan on 9/12/16.
    */
    function Promise(){
    }
    Promise.prototype = {
    callback:null, caller:null,onDone:null,
    when:function(){
    if(this.callbacks){
    this.callbacks = null;
    }
    this.callbacks = [];
    this.caller = null;
    for(var i=0; i!=arguments.length; i++){
    this.callbacks.push({fn:arguments[i], onSuccess:this.onSuccess, onFail:this.fail});
    }
    ///this.callbacks[this.idx].fn.call(this, this);
    return this;
    },
    resolve:function(){
    this.next();
    return this;
    },
    reject:function(){
    this.caller.onFail(this);
    return this;
    },
    done:function(callback){
    this.onDone = callback;
    return this;
    },
    onSuccess:function(promise){
    console.log('on success!');
    },
    next:function(){
    this.caller = null;
    if(this.callbacks.length !== 0){
    this.caller= this.callbacks.shift(1);
    this.caller.fn(this);
    return this;
    }
    if(this.onDone)this.onDone(this);
    return this;
    },
    fail:function(promise) {
    var fn =this.caller.fn;
    this.caller = null;
    throw new EvalError('promise call ' + fn + ' call fail!');
    }
    };
  • 示例

    简单说明下: 通过数组来组成一个链的结构。然后通过resovle和reject配合使用,实现类职责链的效果。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var promise = new Promise();
    promise.when(
    function(promise){ // step 1
    // 在这里调用具体的函数实现,
    // 如果成功,则执行promise.resolve()后,
    // 执行链上的下一个函数,
    // 如果失败,则调用promise.reject(),随后fail()会被执行
    // 如果链上的所有步骤都成功,则最终执行done
    },
    ).next()