2016-02-01 30 views
2

我有以下查詢。 當使用此:何時使用jQuery動畫promise而不是回調?

$('#box').hide(2000).promise().done(function(){ 
    $('#output').text('Box is hidden'); 
}); 

,而不是這樣:

$('#box').hide(2000,function(){ 
    $('#output').text('Box is hidden'); 
}); 

哪些使用.promise()方法與jQuery動畫一些有用的方案是什麼?

謝謝

+4

對於這種情況,根本就沒有什麼。 [更復雜的案例]承諾是有用的(https://gist.github.com/domenic/3889970)。 –

+1

我發現承諾最常用於返回XHR請求或任何其他異步事件的響應。 –

+1

請重新打開此問題。人們對此的回答並不一定要主要是基於意見的。有一個好的支持事實,爲什麼一個人比另一個人好。閱讀提供的答案。這不是主要意見。嘗試編寫一個函數來協調四個不同的定時異步操作,而不使用promise。這是更多的代碼。任何知道如何使用承諾的人都會理解它是如何使用承諾進行更簡單的設計。 – jfriend00

回答

7

如果你只是一個動畫項目,有什麼理由要使用一個承諾通過直接回調。在這種特殊情況下,當您嘗試協調多個不同的異步操作時(承諾一般最有用),promise更有用。

假設你有一大堆你藏起來的物品,並且當他們全部完成時你想要一個回調。那麼,這將做到這一點:

$('.items, .boxes').hide(2000).promise().then(function(){ 
    $('#output').text('All hidden'); 
}); 

或者,假設你想知道何時完成了多個不同的動畫,所以你需要協調多個動作。承諾已經內置功能對於它們更多的工作,以手工代碼而不承諾:

var p1 = $('.items, .boxes').hide(2000).promise(); 
var p2 = $('.sliders').slideUp(2500).promise(); 
var p3 = $('.openers').slideDown(1500).promise(); 
$.when(p1, p2, p3).then(function() { 
    // all are done here 
}); 

如果你想手工代碼,如果沒有承諾,那麼你將不得不保持一個計數器,並在每個單獨的回調,檢查櫃檯看看是否全部完成。這是更多的代碼。現在,如果你有錯誤需要處理或多個其他操作鏈接在一起,任何沒有回調或沒有一些異步支持庫的選項都會很快變成手工代碼的真正痛苦。這就是承諾發明的原因。

或者,甚至超越動畫,想象要協調二者的動畫和Ajax調用(你不知道它需要多長時間):

var p1 = $('.items, .boxes').hide(2000).promise(); 
var p2 = $.ajax(...); 
$.when(p1, p2).then(function() { 
    // both are done here 
}); 

這裏有一個演示通知的差異。如果您按「重置」,然後按「回撥」,您將看到5個完成通知。如果您按下「重置」,然後按下「承諾」,您將看到當完成通知時您會收到1個完成通知。

// configure logging 
 
log.id = "results"; 
 

 
$("#runPromises").click(function() { 
 
    $('.items, .boxes').hide(2000).promise().then(function(){ 
 
     log("got done notification") 
 
    }); 
 
}); 
 
$("#runCallbacks").click(function() { 
 
    $('.items, .boxes').hide(2000, function(){ 
 
     log("got done notification") 
 
    }); 
 
}); 
 

 
$("#reset").click(function() { 
 
    $(".items, .boxes").show(); 
 
    $("#results").empty(); 
 
});
.items { 
 
    height: 50px; 
 
    width: 200px; 
 
    background-color: red; 
 
    margin-top: 10px; 
 
} 
 

 
.boxes { 
 
    height: 30px; 
 
    width: 30px; 
 
    background-color: blue; 
 
    margin-top: 10px; 
 
} 
 
#results { 
 
    margin-top: 30px; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<script src="http://files.the-friend-family.com/log.js"></script> 
 
<button id="runCallbacks">Callbacks</button> 
 
<button id="runPromises">Promises</button> 
 
<button id="reset">Reset</button> 
 
<div> 
 
    <div class="items"></div> 
 
    <div class="items"></div> 
 
    <div class="items"></div> 
 
    <div class="boxes"></div> 
 
    <div class="boxes"></div> 
 
</div> 
 
<div id="results"></div>

+0

'$ .ajax()'自動創建一個承諾,還是需要將最後一個示例調整爲'var p2 = $ .ajax(...)。promise();'? –

+0

@SamAxe - '$ .ajax()'已經返回一個promise。您必須在動畫中使用'.promise()',因爲所有動畫函數的默認值都是返回jQuery對象,因此您可以鏈接jQuery操作,如$(「#box」)。slideUp()。slideDown()',so如果你想要一個承諾,你必須用'.promise()'來請求一個動畫。 – jfriend00

+0

謝謝。這有助於瞭解。 –