2014-09-03 68 views
-1

我在Google搜索jQuery Deferred and Promise for sequential execution of synchronous and asynchronous funcitons上找到了這個腳本。

這可能會解決我的問題,執行腳本sequient順序。但是我用then()函數的問題是我無法知道我可以調用這個函數多少次。我可以調用函數a()3次,下次我可以調用它20次,等等。所以,這對於then()不起作用。那麼()函數不允許數組堆棧。那麼,你們爲了使這個概念有效而做些什麼呢?

fucntion a(counter) 
{ 
    $deferred = $.Deferred(); 

    //Run some scripts here... 
    alert(counter); 

    $deferred.resolve(); 
    return $deferred; 
} 
function Test() 
{ 
    var d = $.Deferred(), 
    p=d.promise(); 
    p.then(a(0)).then(a(1)).then(a(2)); 
    d.resolve(); 
    return d; 
} 

Test().done(function(){ alert('done'); }).fail(function() { alert('fail'); }); 
+0

您正在將'a(N)'返回的'$ deferred'傳遞給'.then()'。相反,您需要傳遞迴調函數,例如'。然後(一)'。 – Bergi 2014-09-03 18:15:01

+1

我不確定當你提到多次調用Test()時你的意思是什麼?這有什麼問題,當你這樣做時你會發生什麼? 「*允許數組堆棧*」是什麼意思? – Bergi 2014-09-03 18:16:28

+0

我更新了問題,我的意思是一個(),而不是測試()... – fletchsod 2014-09-03 18:17:54

回答

2

我想你在問什麼是如何鏈接和未知數量的電話。在這種情況下,您可以輕鬆循環並繼續添加更多.then。例如:

for (var i=0; i < someLimit; i++) { 
    p = p.then(a(i)); 
} 

這將鏈接的調用,使他們被調用一個接一個。如果你想讓它們並行執行,那麼@ jantimon建議使用.when是一條路。

這是因爲鏈接如何工作。撥打.then返回承諾,以便您可以在返回的承諾上再次致電.then。參見:http://api.jquery.com/deferred.then/

+0

謝謝。是的,鏈接的電話數量不詳。我不知道這會起作用。 – fletchsod 2014-09-03 18:32:19

+1

我喜歡你的解決方案,但這也會同時執行它們,不是嗎? – jantimon 2014-09-03 18:34:35

+0

@jantimon:編號'.then'將在延遲解析時執行。所以他們會一個接一個地執行。不要與'.when'混淆 – 2014-09-03 18:36:25

1

您可以使用jQuery.when
請注意,這會併發執行多個異步操作:

jsFiddle Demo

給你a函數返回一個異步的承諾:

function a(counter, $target) { 
    var $deferred = $.Deferred(); 
    setTimeout(function() { 
     $target.text($target.text() + ' ' + counter); 
     $deferred.resolve(); 
    }, 1000); 
    return $deferred; 
} 

在並行:

function Test1() { 
    return $.when($.map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function (val, i) { 
     return a(i, $('#test1')); 
    })); 
} 

Test1().done(function() { 
    $('#test1').css('font-weight', 'bold'); 
}).fail(function() { 
    alert('fail'); 
}); 

要按順序運行它,您需要一個promiseLoop幫助程序:

function promiseLoop(arr, callback) { 
    return arr.reduce(function (previousPromise, val, i) { 
     return previousPromise.then(function (resultArray) { 
      return $.when(callback(val, i)).then(function (res) { 
       return resultArray.concat([res]); 
      }); 
     }); 
    }, $.when([])); 
} 

function Test2() { 
    return promiseLoop([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function (val, i) { 
     return a(i, $('#test2')); 
    }); 
} 


Test2().done(function() { 
    $('#test2').css('font-weight', 'bold'); 
}).fail(function() { 
    alert('fail'); 
}); 
+0

謝謝。如果我需要在平行線程中運行它,我將保存此腳本的副本。 – fletchsod 2014-09-03 18:34:17

+0

查看演示,以並行或按順序運行的示例 – jantimon 2014-09-03 19:12:14

+0

嗯......不錯......謝謝。 :-) – fletchsod 2014-09-03 19:18:13