2017-01-29 17 views
6

Chuỗi Promise này có được đảm bảo thực thi theo thứ tự này không?

function sleep(ms) { 
 
    return new Promise(resolve => setTimeout(resolve, ms)); 
 
} 
 

 
let p = sleep(50); 
 

 
p.then(() => console.log('a')).then(() => console.log('c')); 
 
p.then(() => console.log('b')).then(() => console.log('d'));

Đây có phải là đảm bảo để in "a, b, c, d" để đó? Theo như tôi có thể nói, "a" phải kích hoạt trước "c" và "b" phải kích hoạt trước "d", nhưng ngoài ra, có thể trình thông dịch JS quyết định thực hiện phần còn lại theo thứ tự khác ?

+3

Bản sao có thể có của [Thứ tự lời hứa sau đó() của JavaScript] (http://stackoverflow.com/questions/29111626/javascript-promise-then-ordering) – GSerg

+0

'p.then(). Then()! = P' , nhưng bạn có thể cache "return" của dòng đầu tiên để có được sự bảo đảm – dandavis

+0

@dandavis - điều đó hoàn toàn không có liên quan trong ngữ cảnh này. Ngoài ra - sử dụng! = Sẽ ép buộc mọi thứ. Vì vậy, nó thực sự không thể hiểu những gì bạn đang cố gắng để truyền đạt. –

Trả lời

1

Cách mọi thứ được xếp hàng đợi bằng cách sử dụng setTimeout chính xác là - một hàng đợi. Nếu hai cuộc gọi lại được xếp hàng đợi với cùng một 'độ trễ', cuộc gọi lại được xếp hàng đầu tiên, sẽ kích hoạt trước.

Chỉnh sửa: Tôi không hiểu ý định của OP ban đầu.

Các lời hứa 'Chi nhánh' là những gì thực sự xảy ra ở đây. Có nghĩa là - 'có thể' được tham chiếu trong tập đầu tiên sau đó-ables (cho một & b) sẽ kích hoạt hai cuộc gọi lại được cung cấp cùng lúc bởi vì cả hai tham chiếu cùng một lời hứa - tuy nhiên - bit phức tạp là rằng chúng thực hiện theo thứ tự mà chúng được xếp hàng đợi bằng cách sử dụng đối tượng lời hứa giải quyết của .then(...).

Sau đó, các cuộc gọi lại sau/sau được xếp hàng theo thứ tự tương ứng (c & d).

Để trả lời câu hỏi trực tiếp: Không. Bản chất của các hành động không đồng bộ trong khả năng có thể sau đó có thể là bất kỳ điều gì. Tuy nhiên, các chức năng được cung cấp trong các phần tử sau đó của OP chủ yếu là đồng bộ, dẫn đến thứ tự trực quan - nhưng hoàn toàn gây hiểu lầm.

+1

Tôi tin rằng OP đang sử dụng 'setTimeout' như một hàm async giả cho mục đích thử nghiệm, và chúng sau câu trả lời liên quan đến' then() 's chứ không phải là các đặc tính của' setTimeout'. – GSerg

+0

Ah - Tôi tin rằng bạn hoàn toàn chính xác. Tôi sẽ chỉnh sửa câu trả lời của mình để phản ánh tốt hơn bản chất của OP. –

+1

@GSerg: Điều đó không quan trọng; chỉ có một cuộc gọi không đồng bộ. – SLaks

1

Theo như tôi có thể nói, "a" có bắn trước khi "c" và "b" phải sa thải trước khi "d"

Vâng, đó là nhiều cho certan.

ngoài đó, người phiên dịch JS có thể quyết định thực hiện phần còn lại theo thứ tự khác không?

Phụ thuộc vào người mà bạn hỏi, nhưng không có nhiều đảm bảo rằng làm cho sản lượng dự đoán hơn:

  • các Promise/A+ specification cũng đòi hỏi rằng "tất cả callbacks tương ứng phải thực hiện theo trình tự của các cuộc gọi xuất xứ của họ "Vì vậy, trong ví dụ của bạn, điều đó có nghĩa là" a "phải kích hoạt trước" b ", bởi vì cuộc gọi lại bị xích trước tiên là p.
  • các ECMAScript specification xác định hàng đợi công việc cho lời gọi lại lời hứa, đóng đinh đơn đặt hàng (imo không cần thiết). Nó phù hợp với Promises/A + trong đó các callback "a" và "b" được xếp hàng theo thứ tự chúng được thiết lập khi lời hứa hoàn thành. Nó cũng có nghĩa là sau khi "a" trả về và thực hiện lời hứa, nó sẽ lên lịch "c", và sau khi "b" trả về và hoàn thành lời hứa, nó sẽ lên lịch "d", vì vậy thứ tự của chúng cũng được xác định (đối với các cuộc gọi lại đồng bộ).

Nói chung, không dựa vào bất kỳ thuật toán lập lịch nào, nếu bạn yêu cầu một thứ tự nhất định, hãy làm cho nó rõ ràng.

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