2013-01-18 20 views
17

tôi thấy đoạn mã này mà những gì tôi muốn nó:Promises jQuery và Backbone

var promise = this.model.save(); 
$.when(promise).then(function() { 
    console.log(promise.responseText); 
}); 

Tôi muốn lấy lại responseText từ cuộc gọi Backbone của tôi để this.model.save(). Mã này đã được ghi nhận là here. Nhưng nó không ghi lại bất cứ điều gì, ngay cả khi tôi kéo một chuỗi văn bản thô trong cuộc gọi console.log().

Có thể ai đó vui lòng giải thích các thuật ngữ của giáo dân về lời hứa của jQuery là gì? Tôi đã đọc về họ, nhưng tôi không nghĩ rằng tôi hoàn toàn hiểu được họ là gì. Điều đó có thể giúp tôi hiểu tại sao mã này không hoạt động đối với tôi. Nếu tôi console.log(promise) ở giữa dòng đầu tiên và dòng thứ hai của mã, sau đó tôi nhận được responseText. Vì vậy, có điều gì đó đang xảy ra trong số $.when hoặc then gây ra lỗi này.

EDIT:

Sau khi đọc bài viết này, tôi phát hiện ra tôi có thể làm điều này:

var promise = this.model.save(); 
$.when(promise).then(null, function(obj) { 
    console.log(obj.responseText); 
}); 

Nhưng tôi không hiểu những gì các null đại diện. then dường như có hai tham số, chức năng thành công và chức năng lỗi. Nhưng chức năng thành công không phải là đầu tiên? Tôi nhận được phản hồi 200 từ máy chủ.

+0

đọc http://css.dzone.com/articles/exploring-deferred-and-promise –

+0

Dường như một bài viết hay. Cảm ơn. – sehummel

+0

không có probs :) hạnh phúc đọc .. –

Trả lời

26

Vì vậy, trước hết, tôi chắc chắn bạn không cần phần when; từ các tài liệu jQuery:

The jqXHR objects returned by $.ajax() as of jQuery 1.5 implement the Promise interface, giving them all the properties, methods, and behavior of a Promise (see Deferred object for more information).

Kể từ Promise có một phương pháp then đã có, bạn chỉ có thể làm:

this.model.save().then(null, function(obj) { 
    console.log(obj.responseText); 
}); 

(Thực tế là các mã trên gần như đọc như một câu tiếng Anh là một lợi thế lớn của bằng cách sử dụng Trì hoãn, với tôi ít nhất.)

Đối với đối số null của bạn, các tài liệu lại khá rõ ràng. Có ba chữ ký cho then (và đó chỉ là để trang trải các phiên bản jQuery khác nhau; bất kỳ phiên bản nào có ít hơn):

deferred.then(doneFilter [, failFilter ] [, progressFilter ])

deferred.then(doneCallbacks, failCallbacks)

deferred.then(doneCallbacks, failCallbacks [, progressCallbacks ])

Như bạn có thể thấy, tất cả ba lấy "thực hiện" chức năng đầu tiên, và chức năng thất bại thứ hai. Điều này dường như ngụ ý rằng bạn đang nhận được một thất bại, đó là khó hiểu. Một cách để tránh vấn đề là không sử dụng then. Thay vào đó, hãy thử làm như sau:

this.model.save().always(function(obj) { 
    console.log(obj.responseText); 
}); 

Điều đó sẽ làm cho chức năng của bạn được gọi là không có vấn đề gì xảy ra.Tuy nhiên, có lẽ bạn nên tìm ra những gì đang xảy ra, vì vậy bạn có thể muốn thay vì thêm một thành công và thất bại callback để làm một số sửa lỗi:

this.model.save().done(function() { 
    // Success case 
}).fail(function() { 
    // Failure case 
}); 
+0

những lợi thế của việc sử dụng chậm trễ của jquery thay vì callbacks xương sống đơn giản, như thế này là gì? 'this.model.save ({success: function() { }, lỗi: function() { }});' – Ingro

+2

Đó chỉ là kiểu thực sự. Nếu bạn đang làm những việc phức tạp (như nói hai cuộc gọi AJAX, nơi thứ hai cần dữ liệu quay lại từ cái đầu tiên) thì phong cách trì hoãn cho phép bạn làm điều đó rất tao nhã. Nếu không, nó thực sự chỉ là vấn đề bạn muốn tạo kiểu cho mã của mình như thế nào. Và thực sự đây không phải là vấn đề cụ thể của Backbone; trong jQuery đơn giản, bạn cũng có '$ .ajax ({success: handler});' vs, '$ .ajax ({}). được thực hiện (handler)' để chọn. – machineghost

+0

@machineghost. Cảm ơn bạn đã phản hồi rất kỹ lưỡng. Điều này giải thích rất nhiều. – sehummel

7

this.model.save trả về một lời hứa, bạn có thể làm như sau thay vì:

this.model.save() 
    .done(function(response) { 
     console.log("Success!"); 
    }) 
    .fail(function(response) { 
     console.log("Error!"); 
    }); 

(. Đó là dễ dàng hơn so với toàn bộ $.when bit)

Tôi đoán là mặc dù phản ứng của bạn đang trả lại mã 200 , nó vẫn "thất bại" vì kiểu dữ liệu đáp ứng không khớp với những gì bạn mong đợi (những gì được đặt trong thuộc tính dataType trong cuộc gọi $.ajax).

0

Tôi là một fan hâm mộ lớn của việc sử dụng lời hứa, và tôi nghĩ rằng các phương tiện hứa những thứ rất giống nhau trong các gói khác nhau.

Để trả lời câu hỏi của bạn, câu trả lời trước nào không, hàm "sau đó" là hàm của lời hứa, chức năng "khi" không thể lưu, khi đối tượng không phải là lời hứa, "khi (obj) "sẽ đảm bảo nó là một lời hứa, để bạn có thể sử dụng xxx.then thanh lịch (success() {}, error() {}).

btw, "chậm trễ" mà máy được nói là gói cho phép bạn sử dụng lời hứa. Để bắt đầu biết lời hứa và cách sử dụng nó. xem hướng dẫn này. Nó giải thích mọi điều rất rõ ràng, đó là bài viết khiến tôi thành lời hứa. http://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/

Bây giờ, khi machineghost nói, có vẻ như cuộc gọi đồng bộ hóa của bạn là nhận được một lỗi, theo một tài liệu API REST, https://parse.com/docs/rest# (không biết nếu nó là giống như xương sống), máy chủ sẽ đáp ứng một JSON đối tượng cho một yêu cầu "tạo ra" ở định dạng này:

{"createdAt": "2011-08-20T02:06:57.931Z","objectId": "Ed1nuqPvcm"} 

tôi đoán là, có lẽ máy chủ của bạn không đáp ứng các yêu cầu với JSON đúng, do đó tiết kiệm() nghĩ rằng chiến dịch thất bại vì không có "createAt "trường, sự kiện nghĩ rằng máy chủ của bạn đã tạo mục.