SingleResponseChannel<R> constructor

SingleResponseChannel<R>({
  1. FutureOr<R> callback(
    1. dynamic value
    )?,
  2. Duration? timeout,
  3. bool throwOnTimeout = false,
  4. FutureOr<R> onTimeout()?,
  5. R? timeoutValue,
})

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);
        }
      }
    });
  }
}