SingleResponseChannel<R> constructor
Creates a response channel.
The result is completed with the first value sent to port.
If callback
is provided, the value sent to port is first passed
to callback
, and the result of that is used to complete result
.
If timeout
is provided, the future is completed after that
duration if it hasn't received a value from the port earlier,
with a value determined as follows:
If throwOnTimeout
is true, the the future is completed with a
TimeoutException as an error.
Otherwise, if onTimeout
is provided,
the future is completed with the result of running onTimeout()
.
If onTimeout
is also not provided,
then the future is completed with the provided timeoutValue
,
which defaults to null
.
If the result type, R
, is not nullable, and timeoutValue
is to be used as the result of the future,
then it must have a non-null
value.
Implementation
SingleResponseChannel(
{FutureOr<R> Function(dynamic value)? callback,
Duration? timeout,
bool throwOnTimeout = false,
FutureOr<R> Function()? onTimeout,
R? timeoutValue})
: _receivePort = RawReceivePort(),
_completer = Completer<R>.sync(),
_callback = callback,
_zone = Zone.current {
_receivePort.handler = _handleResponse;
if (timeout != null) {
if (!throwOnTimeout &&
onTimeout == null &&
timeoutValue == null &&
timeoutValue is! R) {
_receivePort.close();
throw ArgumentError.value(null, "timeoutValue",
"The value is needed and the result must not be null");
}
_timer = Timer(timeout, () {
// Executed as a timer event.
_receivePort.close();
if (!_completer.isCompleted) {
if (throwOnTimeout) {
_completer.completeError(
TimeoutException('Timeout waiting for response', timeout));
} else if (onTimeout != null) {
_completer.complete(Future.sync(onTimeout));
} else {
_completer.complete(timeoutValue as R);
}
}
});
}
}