2010-07-20 30 views
8

Có thể làm mọi thứ không đồng bộ trong javascript (AJAX sang một bên) không? Ví dụ, để lặp nhiều mảng cùng một lúc. Làm thế nào là nó được thực hiện? Một ví dụ ngắn gọn sẽ là tốt đẹp. Tìm kiếm cho điều này là khó khăn, do tất cả các ô nhiễm ajax, mà không phải là những gì tôi đang tìm kiếm.Lập trình không đồng bộ trong javascript (NOT AJAX)

Xin cảm ơn trước.

+1

Có vẻ như bạn quan tâm đến việc xử lý song song, không nhất thiết phải thực thi không đồng bộ? Tôi đã không xem xét nó sâu, nhưng không iframes sử dụng một chủ đề js riêng biệt? Tôi không thể tưởng tượng nó sẽ được vui vẻ, nhưng bạn có thể làm một số nhiệm vụ song song bằng cách sử dụng các chức năng trong iframe. – jball

+0

iframe có thể là một kỹ thuật thú vị, mặc dù tôi nghĩ rằng chi phí của iframe sẽ nhiều hơn số âm so với chương trình không đồng bộ tiền thưởng sẽ cung cấp. – aepheus

+0

Ý tưởng thú vị, nhưng tôi nghĩ rằng trong hầu hết hoặc tất cả các trình duyệt, một khung nội tuyến sử dụng cùng một chuỗi JS. Trong thực tế, tôi nghĩ rằng trong tất cả trừ Chrome, tất cả các cửa sổ và tab sử dụng cùng một chuỗi JS. – Grumdrig

Trả lời

9

Sử dụng web Workers. Nhưng hãy nhớ rằng nó là một tính năng rất mới và không phải tất cả các trình duyệt đều được hỗ trợ đầy đủ.

+0

Có bất kỳ tính năng không đồng bộ nào trước html 5 không? – aepheus

+1

@aepheus: Không thực sự - JS được tạo thành một luồng đơn, vì vậy trong khi bạn có thể sử dụng setTimeout() như được thấy trong câu trả lời của Grumdrig, việc thực thi chương trình chỉ chạy trong một chuỗi. – Piskvor

2

Một phát triển mới trong lĩnh vực này là HTML5 Web Workers.

+3

Tuyệt vời, bây giờ có một cách mới thực sự phức tạp để tôi tự hỏi tại sao bộ vi xử lý của tôi đạt đến đỉnh điểm khi truy cập một trang web! : P – Abel

+1

@Abel Tôi đã suy nghĩ cùng một điều. Bây giờ một trang web có thể chốt tất cả 4 cpus thay vì chỉ một. –

+0

Yay, bây giờ chúng ta có thể ghi tất cả 4 CPU với các vòng trống "for" trống! Hãy sẵn sàng cho một số máy tính xách tay HOT! –

6

Bạn có thể sử dụng setTimeout.

setTimeout(function() { iterateArray(array1); reportDone(1); }, 0); 
setTimeout(function() { iterateArray(array2); reportDone(2); }, 0); 

Tôi không chắc chắn nó sẽ như thế nào, nhưng đó là mô hình lập trình không đồng bộ.

+0

+1 Tốt suy nghĩ, đôi khi những điều đơn giản cũ tốt chỉ cần làm :) – Abel

+0

Tôi đoán điều này sẽ vẫn cung cấp cho thực hiện đồng bộ (mặc dù như bạn nhà nước nó sẽ được trong một mô hình không đồng bộ). Mảng 1 sẽ luôn luôn hoàn thành, sau đó mảng 2 sẽ bắt đầu, vv Tôi không thấy nhiều lý do cho điều này ngoài việc làm cho mã khó hiểu. – aepheus

+0

Vâng, tôi hoàn toàn đồng ý. – Grumdrig

1

JavaScript thường là luồng đơn; bạn không thể làm nhiều việc cùng một lúc. Nếu mã JavaScript của bạn quá chậm, bạn sẽ cần phải tắt công việc. Cách mới là sử dụng web workers, như những người khác đã lưu ý. Cách cũ là thường sử dụng AJAX và thực hiện công việc trên máy chủ. (Hoặc là với người lao động web hoặc với AJAX, các mảng sẽ phải được tuần tự và kết quả deserialized)

4

Như đã trình bày bởi Grumdrig bạn có thể viết mã như thế này:

setTimeout(function() { iterateArray(array1); reportDone(1); }, 0); 
setTimeout(function() { iterateArray(array2); reportDone(2); }, 0); 

Nhưng nó sẽ vẫn không chạy đồng thời . Dưới đây là ý tưởng chung về những gì xảy ra sau khi hết thời gian chờ như vậy được gọi là:

  • Bất kỳ mã nào sau khi các cuộc gọi setTimeout sẽ chạy ngay lập tức, bao gồm cả các hàm gọi lại.
  • Nếu có các bộ đếm thời gian khác trong hàng đợi vào hoặc quá thời gian trễ hoặc khoảng thời gian, chúng sẽ được thực hiện từng lần.
  • Trong khi bất kỳ bộ hẹn giờ nào đang chạy, một bộ hẹn giờ khác có thể đạt khoảng thời gian trễ/trễ, nhưng nó sẽ không chạy cho đến khi bộ đếm thời gian kết thúc.
  • Một số trình duyệt ưu tiên các sự kiện được kích hoạt từ tương tác của người dùng như onclickonmousemove, trong trường hợp đó, các chức năng được đính kèm với các sự kiện đó sẽ được thực hiện theo chi phí chính xác của hẹn giờ.
  • Thao tác này sẽ tiếp tục cho đến khi có lệnh mở (không có bộ hẹn giờ hoặc trình xử lý sự kiện nào được yêu cầu thực hiện trước đó). Chỉ sau đó các hàm trong mã ví dụ sẽ được chạy. Một lần nữa, tại một thời điểm, với một lần đầu tiên có khả năng nhưng không chắc chắn thực hiện đầu tiên. Ngoài ra, tôi đang mạo hiểm đoán rằng một số trình duyệt có thể áp đặt thời gian trễ tối thiểu, điều này sẽ làm cho bất kỳ bộ hẹn giờ nào được đặt với độ trễ là 0 mili giây được chạy thậm chí muộn hơn mong đợi.

Rõ ràng không có lợi thế về hiệu suất để chạy mã như thế này. Trong mọi trường hợp, mọi thứ sẽ mất nhiều thời gian hơn để hoàn thành. Tuy nhiên, trong trường hợp một tác vụ mất quá nhiều thời gian để đóng băng trình duyệt (và có thể là các cảnh báo trình duyệt "quá dài"), nó có thể hữu ích để chia nhỏ thành các phần thực thi nhanh hơn chạy tuần tự sau một thời gian trễ , do đó giúp cho trình duyệt có thời gian để thở.

Nhân viên Web đã được đề cập và nếu bạn không quan tâm đến khả năng tương thích của IE thì bạn có thể sử dụng chúng để thực hiện đồng thời đúng. Tuy nhiên có một số hạn chế nghiêm trọng về việc sử dụng chúng được áp dụng vì lý do an ninh.Đối với một người không thể tương tác với DOM theo bất kỳ cách nào, có nghĩa là bất kỳ thay đổi nào đối với trang vẫn phải được thực hiện đồng bộ. Ngoài ra, tất cả dữ liệu được truyền đến và đi từ các công nhân được tuần tự hóa khi chuyển tiếp, có nghĩa là không thể sử dụng các đối tượng Javascript thực sự. Điều đó đang được nói, để xử lý dữ liệu chuyên sâu, các Web Worker có lẽ là một giải pháp tốt hơn là phá vỡ một hàm thành nhiều nhiệm vụ bị trì hoãn.

+0

Nó sẽ giúp làm var tId1 = setTimeout (hàm() {iterateArray (mảng1); reportDone (1);}, 0); var tId2 = setTimeout (function() {iterateArray (mảng2); reportDone (2);}, 0); – mplungjan

+0

Sự khác biệt duy nhất tôi thấy là gán các id hẹn giờ cho các biến. Tất cả các id hẹn giờ là thực sự tốt cho là hủy bỏ giờ nói. Kinda vô nghĩa cho thời gian chờ 0ms chạy một lần. – MooGoo

1

Tôi phải đồng ý với MooGoo, tôi cũng tự hỏi tại sao bạn sẽ chạy qua một mảng lớn như vậy trong một lần.

Có một phần mở rộng cho JavaScript được gọi là StratifiedJS, nó cho phép bạn thực hiện nhiều việc cùng một lúc miễn là chúng không đồng bộ. Ngoài ra, các nhà làm việc web là một "giải pháp" khó xử mà chỉ làm cho mọi thứ phức tạp hơn, ngoài ra, chúng cũng không hoạt động trong IE.

Trong StratifiedJS bạn chỉ có thể viết.

waitfor { 
    // do something long lasting here... 
} 
and { 
    // do something else at the same time... 
} 
// and when you get here, both are done 
Các vấn đề liên quan