2016-09-08 5 views
0

シンプルなコールバック、つまり非同期AJAXコールを実行し、完了したらコールバックする関数のみを使用しました。もう何も複雑になったときは、$ .Deferred()を使いました。問題は、約束を処理することは毎回多くのコードであり、コールバックを正しく使用する方法を知りたいと思います。従属関数のチェーンでjavascriptコールバックを構造化する方法は?

これは私の例です。 (問題は二次からの復帰に発生する()):ここで

function primary() 
{ 
    //call secondary with self as callback 
    var data = secondary("someStr", primary); 
    if (data !== false) { 
     //logic that uses data 
    } 
} 

function secondary(str, callback) 
{ 
    //call the third function. Since we need parameters 
    //on the callback, we create anon function 
    var returnFromThird = tertiary(function() { 
     secondary(str, callback); 
    }); 

    if (returnFromThird !== false) { 
     //when we have data from third do someting.... 
     //but here lies the problem, how do i callback primary()? 
     return returnFromThird + " " + str; 
    } else { 
     //third is not yet ready 
     return false; 
    } 
} 

var myVar3 = null; 
function tertiary(callback) 
{ 
    if (myVar3 === null) { 
     //do async ajax call that sets myVar3 value 
     var ajaxRequest = $.ajax({ 
      url: "/someUrl", 
      type: "POST", 
      data: {myData : "blabla"}, 
      async: true, 
     }); 
     ajaxRequest.done(function(data) { 
      myVar3 = data; 
      //issue the call back, so secondary() can come get myVar3 
      callback(); 
     }); 
     //we did not have the required data so we return false 
     return false; 
    } else { 
     return myVar3; 
    } 
} 

//execute 
primary(); 

は、私は通常、繰延jQueryのを使用して問題を処理する方法を次のとおりです。

function primary() 
{ 
    var promise = secondary(str); 
    $.when(promise).then(
     function (data) { 
      //logic that uses data 
     } 
    ); 
} 

function secondary(str) 
{ 
    var dfd  = $.Deferred(); 
    var promise = tertiary(); 
    $.when(promise).then(
     function (data) { 
      dfd.resolve(data + " " + str); 
     } 
    ); 
    return dfd.promise(); 
} 

var myVar3 = null; 
function tertiary() 
{ 
    var dfd  = $.Deferred(); 
    if (myVar3 === null) { 
     var ajaxRequest = $.ajax({ 
      url: "/someUrl", 
      type: "POST", 
      data: {myData : "blabla"}, 
      async: true, 
     }); 
     ajaxRequest.done(function(data) { 
      myVar3 = data; 
      dfd.resolve(myVar3); 
     }); 

    } else { 
     dfd.resolve(myVar3); 
    } 
    return dfd.promise(); 
} 

primary(); 
+0

をwww.promisejs.org/) –

+0

[延期された反パターンを避ける](http://stackoverflow.com/q/23803743/1048572)、コード全体が少なくなります。 – Bergi

答えて

1

あなたはコールバックを使用している場合は、必ず呼び出す必要があります

var myVar3 = null; 
function tertiary(callback) { 
    if (myVar3 === null) { 
     //do async ajax call that sets myVar3 value 
     $.post("/someUrl", {myData : "blabla"}).done(function(data) { 
      myVar3 = data; 
      callback(data); // just pass the data to the callback 
     }); 
    } else { 
     return callback(myVar3); // always call the callback with the data 
    } 
} 

今、あなたの他の機能は次のようになります:値はコールバックではなく、時にはreturn

function primary() { 
    secondary("someStr", function(data) { 
     //logic that uses data 
    }); 
} 

function secondary(str, callback) { 
    tertiary(function(returnFromThird) { 
     callback(returnFromThird + " " + str); 
    }) 
} 

しかし、あなたは正しいです、あなたは約束を使用する必要があり、それがこの偉大な多くの簡素化://:私は `$ .Deferred`が、[約束パターン](httpsを使用しないことをお勧め

var myVarPromise = null; 
function tertiary() { 
    if (myVarPromise === null) 
     myVarPromise = $.post("/someUrl", {myData : "blabla"}); 
    return myVarPromise; 
} 
function primary() { 
    return secondary("someStr").then(function(data) { 
     //logic that uses data 
    }); 
} 
function secondary(str) { 
    return tertiary().then(function(returnFromThird) { 
     return returnFromThird + " " + str; 
    }); 
} 
+0

私は、(あなたはまだ "コールバック"を持っている)任意の引数とその単なるコピー/ペーストのアーチファクトを持つべきではないと思いますか? – MerlinTheMagic

+0

@Merlinいいえ、 'tertiary' *は' callback'パラメータを必要とします。そうでなければ、その結果をどこに渡すべきか分かりません。 – Bergi

+0

謝罪、私はより具体的でなければならなかった。私はあなたの答えの "約束"バージョンを意味しました。私はそれがコールバックのバージョンで必要であることを理解します。 – MerlinTheMagic

関連する問題