3

パイプではなく、チェーンするだけで、プロミスをチェーンしようとしています。

たとえば、次の方法があります。

var execute = function(x){
   // this could be an AJAX call
   var d= $.Deferred();

    console.log('Begin ' + x);

    setTimeout(function(){
       console.log('End ' + x);            
       d.resolve();
    },500);

    return d;
};

そして、このメソッドを何度も実行したいのですが、次々と実行します。を使用する以外の方法を作成しましたが、使用evalにはあまり満足していませんeval:

var executeTimes = function(r){
    var s = '';
    for(var i=0;i<r;i++){
        s = s + 'execute('+i+')';
        if(i!==r-1)
        s = s + '.then(function(){';
    }

    for(var i=0;i<r-1;i++){
        s= s+'})';
    }

    eval(s);
}

アイデアは、次のexecuteTimes(3);出力を取得することです。

Begin 0 
End 0 
Begin 1 
End 1 
Begin 2 
End 2 

ここにライブの例を作成しました: http://jsfiddle.net/vtortola/Cfe5s/

最善の解決策は何ですか?

乾杯。

4

2 に答える 2

4

ここでは再帰がきれいに見えます:http://jsfiddle.net/Cfe5s/3/

var executeTimes = function(r) {
  (function recurse(i) {
    execute(i).then(function() {
      if(i + 1 < r) {
        recurse(i + 1);
      }
    });
  })(0);
};

で実行される関数を開始し、executeそれ0が完了すると、(再帰を介して)最初からやり直しますが、今回は。で実行し1ます。繰り返す前に、続行するかどうかを確認する必要があります。増分値がまだ。よりも小さい場合にのみ確認してくださいr

于 2012-11-12T18:24:16.523 に答える
2

私のアプローチはあなたのものと似ていますが、文字列を連結する代わりに、関数呼び出しをネストします:P

var executeTimes = function(r){   
    // The last (inner-most) step does nothing. 
    // just in the case we pass r <= 0
    var f = function(){}; 

    for(;  r > 0 ; --r){
        // Create closure with call to execute( ... ).then( ... )
        f = (function(_f, _r){
            return function(){ execute(_r).then(_f); }; 
        })(f, r - 1);
    }
    return f;
}

必要に応じて動作する関数を返します。これを行う場合:

executeTimes​(3)()​​

これにより、例と同じ出力が得られます。この例を簡単に適応させて、任意の関数と最後のステップをサポートできます (関数toExecは呼び出しの「番号」を受け取りたいと想定しています)。

var executeTimes2 = function(toExec /*a function*/, 
                            steps /*a number*/, 
                            finalStep /*a function*/)
{   
    // The last (inner-most) step.
    // just in the case we pass r <= 0
    var f = finalStep? finalStep : function(){}; 

    for(;  steps > 0 ; --steps){
        // Create closure with call to execute( ... ).then( ... )
        f = (function(_f, _r){
            return function(){ toExec(_r).then(_f); }; 
        })(f, steps - 1);
    }
    return f;
}

したがって、関数は次のように 3 回呼び出すことができます。

executeTimes2(execute, 3)()
于 2012-11-12T18:36:46.063 に答える