无耻抄自
Dart Web Development › 如何使用 Isolate.spawn
的示例希望作者不要介意
生成的隔离不知道在哪里/如何响应其父级。
在父级中,您可以创建一个接收端口,它将接收来自子级隔离的所有消息。每当你产生一个隔离时,从你的 ReceivePort 传递一个 SendPort 实例(通过 Isolate.spawn 的 message 参数)。
子隔离也可以/应该创建自己的 ReceivePort,以便它可以接收消息。实例化时,子隔离必须将其自己的 SendPort(从其自己的 ReceivePort)发送到其父级(通过父级的 SendPort)。
当前的 API 本身并没有什么帮助。但它为全面实施提供了所有必要的构建块。
您可能需要将消息包装在标头中,类似于以下内容:
class _Request {
/// The ID of the request so the response may be associated to the request's future completer.
final Capability requestId;
/// The SendPort we must respond to, because the message could come from any isolate.
final SendPort responsePort;
/// The actual message of the request.
final dynamic message
const _Request(this.requestId, this.responsePort, this.message);
}
class _Response {
/// The ID of the request this response is meant to.
final Capability requestId;
/// Indicates if the request succeeded.
final bool success;
/// If [success] is true, holds the response message.
/// Otherwise, holds the error that occured.
final dynamic message;
const _Response.ok(this.requestId, this.message): success = true;
const _Response.error(this.requestId, this.message): success = false;
}
每个隔离都可以有一个像这样的单例消息总线:
final isolateBus = new IsolateBus();
class IsolateBus {
final ReceivePort _receivePort = new ReceivePort();
final Map<Capability, Completer> _completers = {};
IsolateBus() {
_receivePort.listen(_handleMessage, onError: _handleError);
}
void _handleMessage(portMessage) {
if (portMessage is _Request) {
// This is a request, we should process.
// Here we send back the same message
portMessage.responsePort.send(
new _Response.ok(portMessage.requestId, portMessage.message));
} else if (portMessage is _Response) {
// We received a response
final completer = _completers[portMessage.requestId];
if (completer == null) {
print("Invalid request ID received.");
} else if (portMessage.success) {
completer.complete(portMessage.message);
} else {
completer.completeError(portMessage.message);
}
} else {
print("Invalid message received: $portMessage");
}
}
void _handleError(error) {
print("A ReceivePort error occured: $error");
}
Future request(SendPort port, message) {
final completer = new Completer();
final requestId = new Capability();
_completers[requestId] = completer;
port.send(new _Request(requestId, _receivePort.sendPort, message));
return completer.future;
}
}
SendPort anotherIsolatePort = ...
isolateBus.request(anotherIsolatePort, "Some message");
这只是一个架构示例。你当然可以推出自己的。这可以扩展到支持通知(没有响应的请求)、流等。
可能需要一个全局隔离注册表来跟踪来自每个隔离的所有 SendPort 实例,并最终将它们注册为服务。