搜尋套件、儲存庫與 APP 分類

套件詳情v0.1.1

isolated_worker

適用於 Flutter(Isolate)和 Web(Web Worker)的單例隔離工作線程。

AndroidiOSWebmacOSWindowsLinux
近 30 天下載
6420
喜歡數
89
Pub 分數
130

安裝套件

flutter pub add isolated_worker

套件介紹

根據套件公開資料產生的選型評估,僅供參考。

isolated_worker 為 Flutter 與 web 平台提供單例工作器實作,於行動裝置上使用 Isolates,在 web 上則使用 Web Workers。它能透過將繁重任務隔離至背景執行緒,避免阻塞主執行緒,進而提升應用程式回應速度。此套件抽象化各平台差異,提供統一 API,以管理 Android、iOS、Web、macOS、Windows 與 Linux 上的隔離執行。適用於 CPU 負載較高的運算,例如資料解析、影像處理或長時間運算。

適用情境

  • 背景數據處理
  • 圖像或檔案操作
  • 長時間運行的計算
  • 即時資料分析
  • 跨平台後台任務

主要特色

  • 單例工作模式
  • 適用於所有平台的統一 API
  • 自動平台檢測
  • 支援訊息傳遞
  • 內建錯誤處理

適合對象

  • 需要跨平台背景執行的開發者
  • CPU密集型操作的應用程式
  • 重視跨平台程式碼重用的團隊
  • 在密集型任務期間需要響應式 UI 的專案
  • 針對多個作業系統的 Flutter 應用

使用建議

  • 需要理解隔離通訊
  • 限制為一個活動的工作人員實例
  • 訊息序列化開銷
  • 不適合用於輸入/輸出密集型任務,除非有適當的設計
  • 平台特定的限制可能適用

原始 README

以下為關聯原始碼儲存庫的 README 原文快照,最新內容請造訪原始碼儲存庫。

A singleton isolated worker for all platforms. On most platforms, it uses Flutter's Isolate, except on the web, since Isolate is not available, it uses Worker instead.

Features

  • 💙 Easy to use*
  • 👬 Identical syntax to the compute function provided by Flutter*
  • 🚫 Not a one-off worker
  • 🌐 Available on web**

*except on web **by using JsIsolatedWorker

Usage

Basic example
int doSomeHeavyCalculation(int count) {
    // ...
}
void main() {
    // if using compute function:
    // compute(doSomeHeavyCalculation, 1000);
    IsolatedWorker().run(doSomeHeavyCalculation, 1000);
}

If we want to do some heavy work that does not need any arguments and/or return values.

// WRONG
void doSomethingHeavy() {
    // ...
}

// CORRECT
void doSomethingHeavy(void _) {
    // ...
}

void main() {
    IsolatedWorker().run(doSomethingHeavy, null);
}

Web example

We can utilize the JsIsolatedWorker for spawning a web worker. However, it cannot use Dart closures as messages to the worker because of some limitations (I have tried using JSONfn and allowInterop but no luck). Instead we need to use native JS closures. In order to do this, we can utilize existing JS APIs or by importing external libraries/files.

Let's assume we want to stringify objects using JSON.stringify.

void main() {
    JsIsolatedWorker().run(
        functionName: ['JSON', 'stringify'],
        arguments: {},
        // optional argument, in case web worker is not available.
        fallback: () {
            return '{}';
        },
    ).then(print);
    // prints "{}"
}

Now let's assume we have external js libraries/files that we want the worker to use.

void main() async {
    // import the scripts first
    // and check if web worker is available
    final bool loaded = await JsIsolatedWorker().importScripts(['myModule1.js']);
    // web worker is available
    if(loaded) {
        print(await JsIsolatedWorker().run(
            functionName: 'myFunction1',
            arguments: 'Hello from Dart :)',
        ));
    }else{
        print('Web worker is not available :(');
    }
}

Shared Platform Worker

There might be a case where we need to use both IsolatedWorker and JsIsolatedWorker. There are many ways to go about it. We can use conditional import, dependency injections, or WorkerDelegator.

WorkerDelegator

For example, we have a foo Dart method that returns a list of numbers from 1 to count.

List<int> foo(int count) {
    List<int> result = <int>[];
    for(int i = 1; i <= count; i++) {
        result.add(i);
    }
    return result;
}

And a JS file foo.js containing a foo JS method that does the same thing.

function foo(count) {
    let result = [];
    for(let i = 1; i <= count; i++) {
        result.push(i);
    }
    return result;
}

To call these methods using WorkerDelegator, we need to create a DefaultDelegate, JsDelegate, and WorkerDelegate first. Then register the WorkerDelegate to our WorkerDelegator.

Future<void> main() async {
    const DefaultDelegate<int, List<int>> fooDelegate = 
        DefaultDelegate(callback: foo);
    
    const JsDelegate fooJsDelegate = JsDelegate(callback: 'foo');

    const WorkerDelegate<int, List<int>> workerDelegate = 
        WorkerDelegate(
            key: 'foo',
            defaultDelegate: fooDelegate,
            jsDelegate: fooJsDelegate,
        );
    
    WorkerDelegator().addDelegate(workerDelegate);

    // Don't forget to call importScripts for our "foo" js method.
    await WorkerDelegator().importScripts(const <String>['foo.js']);
}

After registering our WorkerDelegate, we just need to call it using its key "foo".

...
print(await WorkerDelegator().run('foo', 9));
...

The key can be anything except null.

enum DelegateKeys { foo, bar }
const WorkerDelegate<int, List<int>> workerDelegate = 
    WorkerDelegate(
        key: DelegateKeys.foo,
        defaultDelegate: fooDelegate,
        jsDelegate: fooJsDelegate,
    );

Notes: WorkerDelegator() is a singleton. If we need to create a new instance, we can create one using

WorkerDelegator.asNewInstance(
    delegates: /* pass our WorkerDelegates here. OPTIONAL. */
);

Web Worker Setup

In order for JsIsolatedWorker to run properly on Flutter web, there needs to be a single worker.js file in the web folder. You can download it here and put it in your web folder like below

...
web /
    index.html
    worker.js
    ...

Examples

  • Fetch - an example of how to get response from a URL using IsolatedWorker and JsIsolatedWorker

所屬分類

依賴

依賴清單 1 項

原始碼儲存庫

使用此套件的專案

暫無相關資料。