2013-04-17 36 views
32

Tôi đang cố gắng kết hợp nhiều cuộc gọi chức năng trì hoãn để cuộc gọi tiếp theo nhận được kết quả của deferred.resolve trước đó. Khi tôi kết nối với nhau hơn 2 trong số các cuộc gọi này, dữ liệu sẽ ngừng được trả lại.Nhiều chức năng trì hoãn chuỗi sử dụng q trong AngularJS dừng trả về dữ liệu

Đây là mã cơ bản bên trong một bộ điều khiển góc:

$scope.runAsync = function() { 
     var asyncFn1 = function(data){ 
      var deferred = $q.defer(); 

      $timeout(function(){ 
       console.log("Async fn1 " + data); 
       $scope.outputLines.push("Async fn1 " + data); 
       deferred.resolve("Async fn1 " + data); 
      },1000); 

      return deferred.promise; 
     } 

     var asyncFn2 = function(data){ 
      var deferred = $q.defer(); 

      $timeout(function(){ 
       console.log("Async fn2 " + data); 
       $scope.outputLines.push("Async fn2 " + data); 
       deferred.resolve("Async fn2 " + data); 
      },1000); 

      return deferred.promise; 
     } 

     asyncFn1(1) 
     .then(function(data){asyncFn2(data)}) 
     .then(function(data){asyncFn2(data)}) 
     .then(function(data){asyncFn2(data)}); 
    } 

Khi tôi chạy này tôi nhận được kết quả như sau:

Async fn1 1 
Async fn2 Async fn1 1 
Async fn2 undefined 
Async fn2 undefined 

Làm thế nào tôi có thể chuỗi chúng với nhau để cuộc gọi thứ ba được kết quả từ cuộc gọi thứ hai và thứ tư nhận kết quả từ cuộc gọi thứ ba?

tôi đã tạo ra một jsFiddle: http://jsfiddle.net/rhDyL/

Trả lời

40

Trích lấy từ doc chính thức về $ q:

sau đó (successCallback, errorCallback) - bất kể khi nào lời hứa đã hoặc sẽ được giải quyết hoặc đã từ chối cuộc gọi thành công hoặc lỗi gọi lại không đồng bộ ngay khi có kết quả. Các cuộc gọi lại được gọi với một đối số duy nhất là kết quả hoặc từ chối lý do.

Phương thức này trả về lời hứa mới là được giải quyết hoặc từ chối qua giá trị trả về của successCallback hoặc errorCallback.

Và đối với các giá trị trở lại của successCallack hoặc errorCallback, theo Domenic's slides:

nếu giá trị trả về là một lời hứa thì hứa hẹn thông qua nhà nước trở lời hứa của nếu không gọi lại thành công là ngay lập tức được gọi là với giá trị trả lại

Dựa trên định nghĩa, mã của bạn thiếu từ khóa return. Nó phải như sau:

asyncFn1(1) 
    .then(function(data){return asyncFn2(data)}) 
    .then(function(data){return asyncFn2(data)}) 
    .then(function(data){return asyncFn2(data)}); 
+0

Wow .. thanks. Tôi thấy nó bây giờ. Tôi chỉ bối rối bởi thực tế là phương thức .then() trả về một lời hứa mới, nhưng bên trong asyncFn tôi trả về một lời hứa từ đối tượng trì hoãn. Dường như gấp đôi số lời hứa. – BoxerBucks

+2

Tôi đã ở cùng một vị trí không lâu trước đây. _Promise & deferred_ yêu cầu một chút về đường cong học tập và thực hành để làm quen với. Tuy nhiên, tôi nghĩ nó đáng giá. Nó làm cho việc quản lý việc thực thi mã trong thế giới lập trình async dễ dàng hơn nhiều. Nếu bạn vẫn chưa quen thuộc với chủ đề này, tôi khuyên bạn nên [đọc này] (http://www.slideshare.net/domenicdenicola/promises-promises). – tamakisquare

+1

@tamakisquare - cảm ơn phản hồi và nhận xét. Tôi nghĩ điểm mấu chốt của sự nhầm lẫn được làm sáng tỏ trong slide # 7 của [trình bày của domenic] (http://www.slideshare.net/domenicdenicola/promises-promises) là nếu giá trị trả về là một lời hứa thì lời hứa sẽ thông qua trở về trạng thái của lời hứa nếu không gọi lại thành công ngay lập tức được gọi với giá trị trả về. Có thể bạn có thể sửa đổi câu trả lời của mình để phản ánh điều đó - để hoàn thiện hơn. Cảm ơn. – Amir

Các vấn đề liên quan