2012-06-28 15 views
6

Bối cảnhLàm thế nào để đối phó với chế biến nặng tải dữ liệu hiển thị trong trình duyệt

  • Chúng tôi có một ứng dụng Ember dựa trên mà xử lý lượng lớn dữ liệu có cấu trúc (mô hình quá trình kinh doanh).
  • Quan trọng! Chúng tôi thực sự muốn giữ cho ứng dụng của mình có thể ngoại tuyến, càng nhiều càng tốt.

Nhu

Trong khi chúng tôi chỉ có để hiển thị các dữ liệu, chỉnh sửa chúng, và như vậy, không có show-stopper trong radar ...

Nhưng bây giờ, chúng tôi muốn áp dụng xử lý trên các mô hình này: kiểm tra tính hợp lệ, tìm đường dẫn ... và một số loại thuật toán tốn thời gian/bộ nhớ.

Vấn đề

Chúng ta có thể xử lý các thuật toán trên máy chủ, nhưng điều đó sẽ giết chế độ ẩn của ứng dụng.

Chúng tôi đã suy nghĩ về công nhân web để tránh các ứng dụng đóng băng và xử lý các thuật toán trong nền, nhưng chúng tôi phải đối mặt với một vấn đề lớn: sao chép dữ liệu khi truyền dữ liệu cho nhân viên. Sử dụng các đối tượng chuyển nhượng sẽ làm cho ứng dụng mất quyền sở hữu (và dữ liệu) trong ít nhất là tính toán, do đó, nó không có vẻ khả thi.

Bạn xử lý vấn đề này như thế nào? Là cách duy nhất của chúng tôi ra việc sử dụng một "coroutine giống như" thực hiện các thuật toán của chúng tôi? Bất kỳ đầu mối?

+0

Tôi nghĩ rằng câu hỏi quan trọng là liệu bạn có đủ tiền để không đóng băng ứng dụng hay không. Giả sử người dùng thực hiện thay đổi đối với dữ liệu trong khi thuật toán đang chạy. Kết quả của quá trình chạy trong nền vẫn hợp lệ/có liên quan? Nếu không, tốt nhất là nên hiển thị cho người dùng thanh tiến trình và tiến hành các tính toán. – Qnan

+0

Sự cố với sao chép dữ liệu là gì? Quá nhiều thứ để tuần tự hóa cho người lao động? –

+0

@SimoneGianni Vấn đề chính là đồng bộ hóa dữ liệu giữa ngữ cảnh giao diện người dùng và bối cảnh công nhân –

Trả lời

3

Nếu mối quan tâm chính của bạn không phải là đóng băng giao diện người dùng trong quá trình xử lý javascript dài, bạn có thể tái cấu trúc các vòng lặp thành các bước tuần tự, sao cho mỗi bước gọi tiếp theo bằng cách sử dụng window.setTimeout. Kỹ thuật này cho phép người (duy nhất) thread để xử lý các sự kiện UI giữa mỗi tương tác:

var pr = function(x) {console.log(x)}; 
var COUNT=3; 

// original regular javascript loop 
for(var i=0; i<COUNT; i++) { 
    var msg = "current index is (" + i + ")"; 
    pr(msg); 
} 

// step-by-step sequential calls 
var body = function(i) { 
    var msg = "non-blocking for: index is (" + i + ")"; 
    pr(msg); 
} 
nonBlockingFor(body, 4); 

Chức năng nonBlockingFor gọi là đối số đầu tiên (như là một chức năng) số lần thông qua như là đối số thứ hai. Định nghĩa của nó là sau:

Xin lưu ý rằng đây là một chức năng rất đơn giản và có thể cải thiện để xử lý các vấn đề liên quan đến nhiều chủ đề khác - tức là: chờ các chủ đề kết thúc (tham gia). Tôi hy vọng mã này sẽ giúp bạn. Vui lòng cho tôi biết nếu bạn thích phương pháp này cho vấn đề này, tôi có thể dành chút thời gian để cải thiện đề xuất của tôi, nếu bạn muốn.

+0

Cảm ơn rất nhiều câu trả lời này. Thực ra, điều đó thực sự gần với cái mà tôi gọi là phương pháp 'giống như coroutine' ... Vấn đề với loại giải pháp này là sự phức tạp thực hiện bùng nổ khi thuật toán có xu hướng phức tạp. :-( –

+1

Phần tốt là, sau khi bạn thiết lập thư viện để chạy javascript không bị chặn/đồng thời, bạn có thể phát triển thư viện kinh doanh theo một hướng thẳng thắn, đồng nhất, bằng cách này, có thể bạn đã biết, nhưng điều này thư viện có vẻ là một ứng cử viên tốt [https://github.com/caolan/async/] –

+0

Cảm ơn bạn đã liên kết. Tôi không biết thư viện này. –

2

thời gian dài đã trôi qua, nhưng vẫn còn: một giải pháp có thể http://jscex.info/

Javascript là đơn luồng trong tự nhiên, và đó là một thiết kế lựa chọn nguyên nhân đa luồng là một chủ đề khó khăn 99% các nhà phát triển javascript thông thường sẽ không xử lý đúng đắn .

Công nhân là cách duy nhất để lấy chuỗi khác và không chặn giao diện người dùng, nhưng để làm cho chúng có thể sử dụng mà không có tác dụng phụ nguy hiểm của đa luồng thực, chúng chạy trong một ngữ cảnh hoàn toàn riêng biệt. Vì vậy, chúng tương tự như gọi một lệnh bên ngoài thông qua các tham số dòng lệnh hơn là sinh ra một luồng khác.Vì vậy, làm việc trong chế độ "không đồng bộ" là giải pháp duy nhất ngay bây giờ, nhưng vì bạn không phải chờ một lần nhấp vào nút hoặc kết nối từ xa để hoàn thành, sự kiện async duy nhất bạn có thể liên kết là dấu tick bộ đếm thời gian, dẫn đến kiểu mã kém gây ra các hoạt động chạy dài trong js. Tuy nhiên, có một thư viện nhỏ, mà tôi thấy rất thú vị và khá nổi tiếng, rằng (mặc dù trang web nghèo nàn của nó) có thể "chuyển đổi" trên bay một mã thủ tục tuyệt đẹp bằng văn bản cho sự lộn xộn của bộ hẹn giờ và chức năng mô hình async vốn đòi hỏi: http://jscex.info/

Như trong cửa sổ 3.1, bạn chỉ cần "thu" ($ await (Jscex.Async.sleep (50));) một số thời gian cho trình duyệt để nó không đóng băng hoàn toàn . Nó sẽ thực sự đóng băng dưới mui xe, nhưng nếu bạn có năng suất thường xuyên không ai sẽ nhận thấy :) (afterall, đó là cách đa nhiệm vẫn hoạt động bên trong mỗi lõi của CPU của bạn, các lát rất nhỏ thời gian trong đó CPU là 100% làm việc trên một tập hợp các hướng dẫn duy nhất .. đưa điều đó đến 20 ms mà không ai có thể biết).

Tôi nghĩ rằng có thể giúp bạn "sản xuất" một JS giống như coroutine mà không thực sự "viết" mã như vậy, nhưng ủy thác cho một "trình biên dịch trước" công việc làm rối tung nó lên.

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