Trì hoãn so với lời hứa


82

Sự khác biệt giữa Deferred và Promise khác với các phiên bản jQuery là gì?

Tôi nên sử dụng những gì cho nhu cầu của tôi? Tôi chỉ muốn gọi fooExecute(). Tôi chỉ cần fooStart()fooEnd()để chuyển đổi trạng thái div html chẳng hạn.

//I'm using jQuery v2.0.0
function fooStart() { /* Start Notification */ }
function fooEnd() { /* End Notification */ }
function fooExecute() { /* Execute the scripts */ }

$('#button1').on('click', function() {
    var deferred1 = $.Deferred();
    var promise1 = $.Promise();

    deferred1.???

    promise1.???
});


2
Bạn không thể thay đổi trạng thái của lời hứa. Do đó, nó được xử lý đối với logic yêu cầu (có thể không có tác dụng gì trong việc can thiệp vào logic điều kiện - để giải quyết hoặc từ chối) - để chờ giải quyết - từ logic nhà máy đã thực sự tạo ra sự trì hoãn đó. Trì hoãn có thể là resolved hoặc rejected thay đổi trạng thái của nó, điều mà Lời hứa của nó cũng sẽ phản ánh. Hãy cho tôi biết bạn muốn sử dụng trả chậm cho các nhấp chuột như thế nào?
Andrevinsky

Tôi không nghĩ rằng ví dụ của bạn có thể được lợi từ những lời hứa (hoặc tôi không hiểu nó). Có thể xem qua Làm thế nào để jQuery hoãn lại được sử dụng? .
Felix Kling

Câu trả lời:


131

Thứ nhất: Bạn không thể sử dụng $.Promise();vì nó không tồn tại.

Một đối tượng hoãn lại là một đối tượng có thể tạo ra một lời hứa và thay đổi trạng thái của nó đến resolvedhay rejected. Trì hoãn thường được sử dụng nếu bạn viết hàm của riêng mình và muốn cung cấp lời hứa cho mã gọi. Bạn là nhà sản xuất của các giá trị.

Một lời hứa là, như tên gọi của mình, một lời hứa về giá trị tương lai. Bạn có thể đính kèm các lệnh gọi lại vào nó để nhận giá trị đó. Lời hứa đã được “trao” cho bạn và bạn là người nhận giá trị tương lai.
Bạn không thể sửa đổi trạng thái của lời hứa. Chỉ mã tạo lời hứa mới có thể thay đổi trạng thái của nó.

Ví dụ:

1. ( sản xuất ) Bạn sử dụng các đối tượng trì hoãn khi bạn muốn cung cấp hỗ trợ hứa hẹn cho các chức năng của riêng bạn. Bạn tính toán một giá trị và muốn kiểm soát thời điểm lời hứa được giải quyết.

function callMe() {
    var d = new $.Deferred();
    setTimeout(function() {
        d.resolve('some_value_compute_asynchronously');
    }, 1000);
    return d.promise();
}

callMe().done(function(value) {
    alert(value);
});

2. ( chuyển tiếp ) Nếu bạn đang gọi một hàm mà bản thân nó trả về một lời hứa, thì bạn không cần phải tạo đối tượng hoãn lại của riêng mình. Bạn chỉ có thể trả lại lời hứa đó. Trong trường hợp này, hàm không tạo ra giá trị, nhưng chuyển tiếp nó (loại):

function fetchData() {
    // do some configuration here and pass to `$.ajax`
    return $.ajax({...});
}

fetchData().done(function(response) {
    // ...
});

3. ( nhận ) Đôi khi bạn không muốn tạo hoặc chuyển các lời hứa / giá trị, bạn muốn sử dụng chúng trực tiếp, tức là bạn là người nhận một số thông tin:

$('#my_element').fadeOut().promise().done(function() {
    // called when animation is finished
});

Tất nhiên, tất cả các trường hợp sử dụng này cũng có thể được trộn lẫn. Hàm của bạn có thể là bộ nhận giá trị (từ một lệnh gọi Ajax chẳng hạn) và tính toán (tạo ra) một giá trị khác dựa trên đó.


Câu hỏi liên quan:


2

Một lời hứa là một cái gì đó bạn có thể thiết lập trên một đối tượng hoãn lại thực thi khi bộ sưu tập hoãn lại hoàn tất.

Ví dụ từ tài liệu jQuery :

<!DOCTYPE html>
<html>
<head>
  <style>
div {
  height: 50px; width: 50px;
  float: left; margin-right: 10px;
  display: none; background-color: #090;
}
</style>
  <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>

<button>Go</button>
<p>Ready...</p>
<div></div>
<div></div>
<div></div>
<div></div>


<script>
$("button").on( "click", function() {
  $("p").append( "Started...");

  $("div").each(function( i ) {
    $( this ).fadeIn().fadeOut( 1000 * (i+1) );
  });

  $( "div" ).promise().done(function() {
    $( "p" ).append( " Finished! " );
  });
});
</script>

</body>
</html>

Đây là trong JSFiddle

Điều này chạy một chức năng trên mỗi divvà thực thi .promisemã khi tất cả các quá trình .eachthực thi hoàn tất.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.