2013-06-12 18 views
8

Tôi có một chức năng cần kết quả của ba lời hứa trước đó được truyền cho nó. Một là phụ thuộc tuyến tính và hai loại kia có thể chạy đồng thời. Tôi muốn sử dụng q.all để giải quyết ba lời hứa, và sau đó chuyển kết quả vào thứ tư bằng cách sử dụng .spread. Mã của tôi tuy nhiên không hoạt động. Bất kỳ trợ giúp sẽ được đánh giá cao.kriskowal/q node.js q.all và lây lan

var p1 = doWork(data); 
var p2 = p1.then(doMoreWork); 
var p3 = doConcurrentWork(data); 

return q.all([p1,p2,p3]).spread(funcWith3params) 
     .fail(function(err) { 
      console.log(err): 
     } 

Tôi có thể theo dõi mã trong trình kiểm tra nút và thấy rằng 3 lời hứa đầu tiên đang được gọi. Tuy nhiên, chức năng mà các cuộc gọi .spread không được gọi. Bất kỳ manh mối nào về lý do tại sao? Ngoài ra .fail cũng không bị tấn công.

+0

Tôi giả sử bạn có nghĩa là đặt dấu đóng ')' trong đó. – Sukima

Trả lời

7

Thực hiện cuộc gọi q.all nội bộ.

Đây là mã cho lây lan từ q.js:

Q.spread = spread; 
function spread(promise, fulfilled, rejected) { 
    return when(promise, function (valuesOrPromises) { 
     return all(valuesOrPromises).then(function (values) { 
      return fulfilled.apply(void 0, values); 
     }, rejected); 
    }, rejected); 
} 

Lưu ý rằng họ hy vọng một lời hứa mà giải quyết cho một mảng hoặc một mảng như là đối số đầu tiên.

Do đó cuộc gọi của bạn sẽ trông như thế này:

var p1 = doWork(data); 
var p2 = p1.then(doMoreWork); 
var p3 = doConcurrentWork(data); 

return q.spread([p1,p2,p3], funcWith3params, function(err) { 
     console.log(err): 
    }); 

Tuy nhiên, cuộc gọi ban đầu của bạn nên làm việc là tốt. Không chắc chắn tại sao nó không.

3

Cách cô đọng nhất để diễn tả ví dụ bạn đã cung cấp là:

var p1 = doWork(data); 
var p2 = p1.then(doMoreWork); 
var p3 = doConcurrentWork(data); 

return Q.spread([p1, p2, p3], funcWith3params) 
    .done(); 

Tuy nhiên, ban đầu là đúng như bằng văn bản.

Tôi nghi ngờ rằng vấn đề là một hoặc nhiều lời hứa nhập liệu sẽ không bao giờ giải quyết. Hãy thử sử dụng hết thời gian chờ để tách biệt vấn đề.

var p1 = doWork(data).timeout(1000, 'p1 timed out'); 
var p2 = p1.then(doMoreWork).timeout(1000, 'p2 timed out'); 
var p3 = doConcurrentWork(data).timeout(1000, 'p3 timed out'); 

return Q.spread([p1, p2, p3], funcWith3params) 
    .done(); 
+2

Tôi đã nhìn thấy việc sử dụng '.done()' mà không có arg và một số ví dụ với args. Có sự khác biệt và/hoặc thực hành tốt nhất? – Sukima

+2

@Sukima 'done()' được sử dụng để đóng một cách rõ ràng chuỗi lời hứa, tức là bạn không thể mong đợi các trình xử lý 'sau đó' nữa kích hoạt ngoài lời gọi đến' done'. – Renaud