2012-12-10 28 views
15

Tôi thực sự đang gặp khó khăn ở đây để hiểu thấu bằng cách viết JavaScript không đồng bộ. bạn có thể vui lòng cung cấp một ví dụ về một hàm JavaScript đơn giản là không đồng bộ viết bằng đồng bằng JavaScript (và không sử dụng Node.js hoặc JQuery)Ví dụ đơn giản về hàm javascript không đồng bộ là gì?

+2

'setTimeout' ??? – Bergi

+1

Trình xử lý sự kiện. –

+0

@SLaks đọc câu trả lời của Bergi. Đó là cơ bản những gì tôi đang đề cập đến. – Ryan

Trả lời

28

Bản thân JavaScript là đồng bộ và đơn luồng. Bạn không thể viết một hàm không đồng bộ; JS đơn giản không có API thời gian. Sẽ không có tác dụng phụ từ các luồng song song.

Điều bạn có thể làm là sử dụng một số API do môi trường của bạn cung cấp (Node.js, Webbrowser) cho phép bạn lên lịch các tác vụ không đồng bộ - sử dụng timeouts, ajax, FileAPI, requestAnimationFrame, nextTick, WebWorkers, DOM events.

Một ví dụ sử dụng setTimeout (cung cấp bởi HTML Timing API):

window.setTimeout(function() { 
    console.log("World"); 
}, 1000); 
console.log("Hello"); 

Cập nhật: Kể từ ES6 có những lời hứa như một nguyên thủy không đồng bộ xây dựng vào đồng bằng Javascript, vì vậy bạn có thể làm

Promise.resolve("World").then(console.log); // then callbacks are always asynchronous 
console.log("Hello"); 

Tuy nhiên, chúng không thực sự hữu ích khi bạn không thể chờ đợi (chẳng hạn như thời gian chờ). Và chúng cũng không thay đổi bất cứ điều gì về mô hình luồng, tất cả việc thực hiện là chạy hoàn thành mà không có bất kỳ sự kiện nào can thiệp vào giữa chừng.

+1

Câu trả lời hay, nhưng là một ví dụ sử dụng 'bind' thực sự cần thiết? Có thể gây nhầm lẫn cho OP hơn nữa ... – bfavaretto

+0

+1, rất đúng; nhiệm vụ 'async' chỉ là những nhiệm vụ được chuyển trong hàng đợi thực hiện. Do đó thủ thuật hữu ích (đôi khi) với 'setTimeout (func, 0)'.) – raina77ow

+0

@bfavaretto: Không muốn lặp lại câu trả lời của Xeano. Thay đổi ngay bây giờ để giảm bớt sự nhầm lẫn :-) – Bergi

7

này là không đồng bộ:

setTimeout(function(){ 
    console.log('1'); 
}, 2000); 

console.log('2'); 

2 sẽ được ghi vào giao diện điều khiển trước 1. Vì setTimeout không đồng bộ.

7

Dưới đây là một ví dụ rất đơn giản:

for (var i = 0; i < 10; i++) { 
    window.setTimeout(function() { 
    console.log(i); 
    }, 2000); 
} 

Bạn có thể mong đợi những console.log() cuộc gọi đến cho bạn thấy 0, 1, 2 vv, như trong đoạn này:

for (var i = 0; i < 10; i++) { 
    console.log(i); 
} 

Nhưng trong thực tế, chỉ 10 s sẽ in! Lý do mà các chức năng thông qua vào setTimeout chức năng (như 'callback' đối số của nó) sẽ được gọi saufor vòng lặp được hoàn thành - tức là, sau khi giá trị i được thiết lập đến 10

Tuy nhiên, bạn nên hiểu một điều: tất cả các hoạt Javascript trong một trình duyệt thực hiện trên một chuỗi duy nhất; sự kiện không đồng bộ (chẳng hạn như lần nhấp chuột và bộ tính giờ) chỉ chạy khi có một mở trong hàng đợi thực hiện. Đây là a brilliant article được viết bởi John Resig về chủ đề này.

+5

Vấn đề với vòng lặp là vấn đề phạm vi, không phải vì bản chất không đồng bộ. Nếu chúng được sắp xếp đúng, vòng lặp sẽ hoạt động như mong đợi. Mặc dù đó là một lời giải thích tốt về các hàm được truyền cho 'setTimout' thi hành _after_ vòng lặp' for' – Ian

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