2009-07-22 11 views
19

Vì vậy, tôi bắt đầu nghe nhiều hơn và nhiều hơn nữa về Web Workers. Tôi nghĩ rằng nó hoàn toàn tuyệt vời, nhưng câu hỏi mà tôi chưa từng thấy bất cứ ai thực sự giải quyết cho đến nay là làm thế nào để hỗ trợ các trình duyệt cũ mà chưa có hỗ trợ cho công nghệ mới.Giảm mức độ duyên dáng với Nhân viên Web

Giải pháp duy nhất tôi có thể đưa ra cho đến nay là làm cho một số loại trình bao bọc xung quanh chức năng của nhân viên web sẽ quay trở lại giải pháp dựa trên bộ đếm thời gian điên sẽ mô phỏng thực thi đa luồng.

Nhưng ngay cả trong trường hợp đó, làm cách nào để phát hiện xem nhân viên web có phải là tính năng được hỗ trợ của trình duyệt hiện đang thực thi javascript không?

Cảm ơn!

+0

Tôi nghĩ rằng một phụ lục tốt sẽ là nếu Web Workers không có sẵn, chúng ta có thể kiểm tra xem chúng ta có thể sử dụng Google Gears 'Worker Pool –

Trả lời

11

Đây là vấn đề phát triển web lâu đời: phải làm gì với các trình duyệt không hỗ trợ những gì bạn cần. Hiện tại, tôi chỉ chủ trương sử dụng các Web Worker cho các tác vụ phức tạp, dài hạn có thể bị phá vỡ và vì một lý do nào đó, không thể thực hiện được phía máy chủ. Bằng cách này, nếu bạn không có Web Worker, bạn chỉ cần đợi lâu hơn. Nếu không, bạn sẽ phải thực hiện một mớ hỗn độn của mã của bạn với hàm bao và những gì bạn sẽ cố gắng tránh sau này. Chiến lược suy thoái của tôi xảy ra ngay sau khi trang được tải.

onload chức năng giả:

if(window.Worker /*check for support*/) 
    someObject.myFunction = function() { /*algorithm that uses Web Workers*/ } 
else 
    someObject.myFunction = function() { /* sad face */ } 

Bạn vẫn phải viết các thuật toán hai lần, nhưng bạn sẽ phải làm điều đó anyway nếu bạn muốn hỗ trợ các trình duyệt mà không cần Web Workers. Vì vậy, nó sẽ trả lời một câu hỏi thú vị: liệu nó có xứng đáng với thời gian (và tiền bạc) để viết một cái gì đó hai lần, chỉ để nó có thể đi nhanh hơn một chút cho một số người?

+0

"supportWebWorkers" ... –

+0

@Jelel: 'if (Worker) ...' – geowa4

+0

@Joel: chỉnh sửa cho rõ ràng – geowa4

1

Đây là những gì John Resig nói replying to a comment on his blog

Tôi nghĩ về điều này - nhưng nó sẽ được khéo léo. Bạn sẽ phải làm cho mã xử lý của bạn sử dụng setTimeout/setInterval ngay từ đầu (mã này sẽ kết thúc làm việc trong cả một nhân viên và trên một trang web bình thường). Vì vậy, trong khi kết quả sẽ hơi chậm hơn cho các trình duyệt cho phép nhân viên ít nhất nó sẽ hoạt động trong cả hai trường hợp.

2

Dự án Bespin có (cái mà họ gọi) là facade cho phép họ chạy mã JavaScript trong Công nhân Web, Công nhân bánh răng và nếu không có sẵn trong chủ đề chính.

4

Sau khi nhai về vấn đề này trong một vài ngày, tôi đã kết thúc viết một bài viết trên blog của tôi:
http://codecube.net/2009/07/cross-platform-javascript-webworker/

Ý tưởng là trong trường hợp WebWorker không được định nghĩa, có một API wrapper mà chỉ sử dụng kỹ thuật tích hợp sẵn. Mặc dù mẫu trong bài viết rất đơn giản, nhưng nó hoạt động trong tất cả các trình duyệt :-)

+0

Liên kết không còn khả dụng: ( –

+0

Một snafu DNS tạm thời, xin lỗi của tôi. liên kết bộ nhớ cache của google :) http://webcache.googleusercontent.com/search?q=cache:v3Kwpb0TXtoJ:codecube.net/2009/07/cross-platform-javascript-webworker/+&cd=1&hl=vi&ct=clnk&gl=us –

0

Tôi gặp vấn đề buồn cười khi nhiệm vụ của tôi không hỗ trợ Web Worker quá chậm trong Firefox (không đáp ứng), nhưng đủ nhanh các trình duyệt hiện đại khác. Với các Web Worker, nó hoạt động trên tất cả các trình duyệt ngoại trừ Opera (10.50) không hỗ trợ Web Worker, nhưng Opera làm việc tốt mà không cần đến chúng.

Vì vậy, tôi đã viết một WorkerFacade sử dụng API Web Worker khi có sẵn hoặc giả mạo API với một số bổ sung nhỏ cho JS Worker thực tế. Bạn có thể tìm thấy WorkerFacade as a gist on GitHub. Làm việc tốt cho tôi, cũng có thể giúp đỡ người khác.

+0

Cập nhật: [Opera hiện hỗ trợ Web Workers] (http://caniuse.com/#search=webworker). – tjameson

0

@ geowa4

//globals 
var useWorer={} 
    ,noWorkerClosure=function(){...} 
    ,myWorkerClosure=function(){...} 
    ; 
function init(){ 
     if(!!window.Worker){ 
      noWorkerClosure=null; 
      useWorer=new myWorkerClosure(); 
     } 
     else{ 
      useWorer=new noWorkerClosure(); 
      myWorkerClosure=null; 
     } 
} 

Bằng cách này, bạn giải phóng tải lượng bộ nhớ và không cần yêu cầu hỗ trợ mỗi lần.