搜索插件、代码仓与 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。它通过将耗时任务隔离到独立线程,避免阻塞主线程,从而提升应用的响应能力。该包抽象了平台差异,为 Android、iOS、Web、macOS、Windows 和 Linux 提供统一的 API 来管理隔离执行。适用于 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 项

源码仓库

使用此插件的项目

暂无相关数据。