Skip to content

Instantly share code, notes, and snippets.

@marceloneppel
Forked from eduardocp/async_helper.dart
Created October 15, 2018 23:21
Show Gist options
  • Save marceloneppel/20c6c7d1b99fea210893930a8ba1c040 to your computer and use it in GitHub Desktop.
Save marceloneppel/20c6c7d1b99fea210893930a8ba1c040 to your computer and use it in GitHub Desktop.
Helper to do async methods in other thread in flutter
import 'dart:isolate';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
enum AsyncState { idle, loading, running }
class AsyncMessage {
final Function asyncMethod;
List data;
SendPort sendPort;
AsyncMessage(this.asyncMethod, this.data, this.sendPort);
}
class AsyncManager {
final Function asyncMethod;
final Function(dynamic message) onSuccess;
final Function onError;
final ReceivePort _receivePort;
final ReceivePort _errorPort;
Isolate _isolate;
AsyncState _state = AsyncState.idle;
AsyncState get state => _state;
bool get isRunning => _state != AsyncState.idle;
AsyncManager({@required this.asyncMethod, this.onSuccess, this.onError})
: assert(asyncMethod != null),
_receivePort = ReceivePort(),
_errorPort = ReceivePort() {
_receivePort.listen(_receiveMessage, onError: _receiveMessage);
_errorPort.listen(_errorMessage);
}
void start(List data) {
if (!isRunning) {
_state = AsyncState.loading;
_run(data);
}
}
void stop() {
if (isRunning) {
_state = AsyncState.idle;
if (_isolate != null) {
_isolate.kill(priority: Isolate.immediate);
_isolate = null;
}
}
}
void _errorMessage(dynamic message) {
stop();
onError?.call(message);
}
void _run(List data) {
if (isRunning) {
final AsyncMessage message = AsyncMessage(asyncMethod, data, _receivePort.sendPort);
Isolate.spawn<AsyncMessage>(_execute, message, onError: _errorPort.sendPort).then((Isolate isolate) {
if (!isRunning) {
isolate.kill(priority: Isolate.immediate);
} else {
_state = AsyncState.running;
_isolate = isolate;
}
});
}
}
void _receiveMessage(dynamic message) {
onSuccess?.call(message);
}
static void _execute(AsyncMessage message) async{
final SendPort sender = message.sendPort;
var result = await Function.apply(message.asyncMethod, message.data);
sender.send(result);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment