搜索插件、代码仓与 APP 分类

GitHub 代码仓iandis/isolated_worker

isolated_worker

用于 Flutter(Isolate)和 Web(Web Worker)的隔离工作线程。其行为几乎与 compute 函数相同,但不是一次性工作线程。

isolated_worker 项目封面
星标
42
复刻
11
最近推送(UTC)
2024年11月5日
项目状态
未归档

原始 README

以下为英文项目原文快照,最新内容请访问 GitHub。

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
Iandi Santulus GitHub avatar
GitHub 作者

Iandi Santulus ↗

frontend dev specializes in Flutter

语言DartJavaScript

此仓库发布的插件

使用的依赖

依赖清单 3 项

如何选择适合项目的代码仓?

先按使用场景筛选,再比较项目活跃情况,最后到原始仓库核对使用要求。

  1. 通过仓库名、作者或描述搜索,再按技术分类缩小范围。
  2. 结合星标、复刻与最近推送比较项目;星标反映社区关注,不代表质量保证。
  3. 使用前在 GitHub 核对 README、许可证与 Issues。

来源与维护

“A repository is the most basic element of GitHub.”

GitHub Docs — About repositories ↗