Dart/Flutter - 从回调函数中产生

Dart/Flutter - yield from callback function

我需要进行一个函数调用,它不会 return 任何东西 (void)。获得函数完成通知的唯一方法是发送 callback 函数。
现在我使用 BLoC 模式和 ReDux,当一个事件被分派时,我分派另一个动作来存储 redux,在 action 完成后它调用 callback 函数。现在在 callback 函数中,我想更新 blocstate。下面是我的实现,

if (event is Login) {
  yield currentState.copyWith(formProcessing: true);
  store.dispatch(authActions.login(
    currentState.username,
    currentState.password,
    (error, data) {
      print(error);
      print(data);
      // I want to yield here.
      yield currentState.copyWith(formProcessing: false);
    },
  ));
}

如上面的代码片段所示,在回调函数里面,我想yield.

解决方案

创建一个 return 未来的函数,并制作回调函数来存储分派,这里是示例。

if (event is Login) {
  yield currentState.copyWith(formProcessing: true);

  try {
    dynamic result = await loginAction(store, currentState.username, currentState.password);
    print(result);
    yield currentState.copyWith(formProcessing: false);
  } catch (e) {
    print(e);
  }
}

Future loginAction(store, username, password) {
  var completer = new Completer();

  store.dispatch(authActions.login(
    username,
    password,
    (error, data) {
      if (error != null) {
        completer.completeError(error);
      } else if (data != null) {
        completer.complete(data);
      }
    },
  ));

  return completer.future;
}

您需要在您的 callback 函数中创建其他 eventdispatch 这个 event,然后您可以在过滤您的函数中执行您想要的操作events.

我不知道你的 BLoC 的目的是什么,但是这个 event 的名称取决于用例,它可以是 UpdateFormUpdateStateLoggedInLoggedOut 等。您会为您的用例找到最具描述性的名称。

记住你也可以创建这个event带参数,例如UpdateForm (bool isLoggedIn),和yield根据你的条件不同states

例如,这个event的名称是OtherEvent

if (event is Login) {
  yield currentState.copyWith(formProcessing: true);
  store.dispatch(authActions.login(
    currentState.username,
    currentState.password,
    (error, data) {
      print(error);
      print(data);

      dispatch(OtherEvent());
    },
  ));
} else if (event is OtherEvent) {
   // You can yield here what you want
   yield currentState.copyWith(formProcessing: false);
}