2017-01-22 26 views
7

Tôi đang học Promise, để hiểu nó, tôi đã đọc một chút về vòng lặp Sự kiện của JavaScript. Điều này article giới thiệu ngắn gọn công việc của vòng lặp sự kiện chẳng hạn như ngăn xếp cuộc gọi, bảng sự kiện và hàng đợi tin nhắn.Hiểu thứ tự thực hiện của các trình xử lý sau đó() của lời hứa đã giải quyết

Nhưng tôi không biết cách ngăn xếp cuộc gọi đối phó với dòng chứa 'trả lại' và điều gì xảy ra sau đó. Dưới đây là một ví dụ mà tôi đã viết để hy vọng hiểu cách Promise hoạt động dựa trên vòng lặp sự kiện. Ngoài ra, hãy xem http://jsbin.com/puqogulani/edit?js,console nếu bạn muốn sử dụng.

var p1 = new Promise(
    function(resolve, reject){ 
    resolve(0); 
}); 

p1.then(function(val){ 
    console.log(val); 
    p1.then(function(){ 
    console.log("1.1.1"); 
    p1.then(function(){ 
     console.log("1.1.2"); 
     p1.then(function(){ 
     console.log("1.1.3"); 
     }); 
    }); 
    }); 

    p1.then(function(){ 
    console.log("1.2"); 
    }) 

    return 30; 

    //return new Promise(function(resolve, reject){ 
    // resolve(30); 
    //}); 

}) 
    .then(function(val){ 
    console.log(val/2); 
}); 

p1.then(function(){ 
    console.log("2.1"); 
}); 

console.log("Start"); 

Như có thể thấy, có hai "trả lại", mỗi người dùng sẽ cung cấp thứ tự đầu ra khác nhau. Cụ thể, khi sử dụng return 30;, 1.1.2, 1.1.3 là sau 15, nhưng khi sử dụng return new Promise(...), 1.1.2, 1.1.3 trước 15. Vì vậy, chính xác những gì đã xảy ra khi mã đạt hai 'trở lại' khác nhau?

+1

Removed callbacks của 1.1.4 và 1.1.5 - chúng không được nhắc đến và làm cho nó không dễ hiểu hơn và mọi người đều có điểm lên đến 1.1.2 rồi. Mọi người sẽ vẫn có thể hiểu được tiến thoái lưỡng nan mà không có họ. –

+0

@ try-catch-finally, Cảm ơn bạn đã đề xuất và chỉnh sửa. Tôi chỉ muốn làm cho nó rõ ràng hơn, mặc dù đôi khi nó làm cho đối diện :) –

+0

Vì vậy, @ try-catch-cuối cùng, tôi tự hỏi nếu bạn có thể đưa ra lời khuyên về câu hỏi của tôi? Cảm ơn bạn –

Trả lời

2

Sự khác biệt được mô tả trong http://promisesaplus.com/ theo quy trình giải quyết lời hứa.

Đối với giá trị trả về đầu tiên:

2.3.3.4 Nếu sau đó không phải là một chức năng, thực hiện lời hứa với x.

Đối với phần thứ hai:

2.3.2 Nếu x là một lời hứa, thông qua trạng thái của nó [3,4]:

2.3.2.2 Nếu/khi x được hoàn thành, thực hiện lời hứa với cùng giá trị.

Chúng tôi có thể thấy điều này được triển khai q.js. Đây là một thực hiện tốt nhưng dường như giải thích sự chậm trễ:

function coerce(promise) { 
    var deferred = defer(); 
    Q.nextTick(function() { 
     try { 
      promise.then(deferred.resolve, deferred.reject, deferred.notify); 
     } catch (exception) { 
      deferred.reject(exception); 
     } 
    }); 
    return deferred.promise; 
} 

Khi trở về một lời hứa từ then chức năng, chúng ta có hai đối tượng hứa hẹn riêng biệt: một sự trở về từ các hàm được chuyển vào then, và một trong những trở về từ then. Chúng cần được kết nối với nhau để giải quyết vấn đề thứ nhất, giải quyết vấn đề thứ hai. Điều này được thực hiện với promise.then(deferred.resolve, ...)

Độ trễ đầu tiên đến từ Q.nextTick. Điều này thực thi hàm trên vòng lặp tiếp theo của vòng lặp sự kiện. Có một số cuộc thảo luận trong số commit comments về lý do tại sao cần.

Gọi promise.then thêm trễ hơn một lần lặp vòng lặp sự kiện. Theo yêu cầu trong thông số:

2.2.4 onFulfilled or onRejected không được gọi cho đến khi ngăn xếp ngữ cảnh thực thi chỉ chứa mã nền tảng. [3.1].

Việc thực hiện sẽ đi một cái gì đó như:

p1.then with function containing 1.1.1 is called 
    function containing 1.1.1 is queued 
p1.then with function containing 1.2 is called 
    function containing 1.2 is queued 
Promise resolving to 30 is returned 
    Q.nextTick function is queued 
---------- 
1.1.1 is printed 
p1.then with function containing 1.1.2 is called 
    function containing 1.1.2 is queued 
1.2 is printed 
Q.nextTick function is executed 
    promise.then(deferred.resolve, ...) is queued 
---------- 
1.1.2 is printed 
p1.then with function containing 1.1.3 is called 
    function containing 1.1.3 is queued 
promise.then(deferred.resolve, ...) is executed 
    function containing val/2 is queued 
---------- 
1.1.3 is printed 
val/2 is printed 
+0

Cảm ơn bạn rất nhiều vì bài viết của bạn rất rõ ràng những gì tôi muốn biết ! –

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