当我在网络调用后完成完成时,分配给我的 Compler.future 对象的回调没有被调用

The call back assigned to my Compler.future object is not being called when I complete the completer after a network call

我是 Dart 新手,有 iOS 背景,所以我可能使用的语言不正确,这导致我的代码无法按预期工作,但我也无法在网上找到解决方案,我想我会问它在这里,以防其他人经历过并修复它。

所以我想要完成的是让模型工厂创建一个数据源,您可以在其中传递请求类型(GET 或 POST)、传递端点和一些参数。然后它将 return 你返回一个未来,你在其中监听 then() 调用,当网络请求是 successful/fails 时调用。我目前使用的代码一直工作到我调用 completion.complete(responseObject);...之后什么都没有发生。

涉及的几个函数的代码:

模型工厂内部:

BaseDataSource bds = new BaseDataSource();
Map params = {"api_key": "random","session_id": "random", "account_id": "random"};
Future<Map> request = bds.makeRequest(NetworkingRequestType.GET, params, "music/songs");
request.then((Map responseObject) {

});

数据源内部:

enum NetworkingRequestType {
   GET, POST
}

class BaseDataSource {

  static final String baseServerURL = config[appRunMode]["baseServerURL"];

  Future<Map> makeRequest(NetworkingRequestType type, Map params, String endpoint) {
    Future<Map> completion;

    switch (type) {
      case NetworkingRequestType.GET:
        completion = _makeGetRequest(endpoint, params);
        break;

      case NetworkingRequestType.POST:
        break;
    }

    return completion;
  }

  Future<Map> _makeGetRequest(String endpoint, Map params) {
    final uri = new Uri(path: "${baseServerURL}${endpoint}",
    queryParameters: params);
    return HttpRequest.getString("${uri}").then(JSON.decode);
  }
}

我无法发现此代码有任何问题,除了它不会传播错误。它应该工作。如果 completion.complete 被调用,那么 completion.future 必须完成,检查 completion.complete 确实被调用(例如检查控制台上是否有任何网络错误,检查 DevTools 中的网络选项卡以查看 request/response).

一般来说,我建议避免显式使用完成符。只需使用 then 返回的未来而不是 completer.future:

  Future<Map> makeRequest(NetworkingRequestType type, Map params, String endpoint) {
    switch (type) {
      case NetworkingRequestType.GET:
        return _makeGetRequest(endpoint, params);

      case NetworkingRequestType.POST:
        break;
    }
  }

  Future<Map> _makeGetRequest(String endpoint, Map params) {
    final uri = new Uri(path: "${baseServerURL}${endpoint}",
                        queryParameters: params);
    return HttpRequest.getString("${uri}").then(JSON.decode);
  }

你的代码在我看来像是使用 Completer 和不使用 Completer 的混合体。

使用 Completer 时代码的样子:

Future<Map> makeRequest(NetworkingRequestType type, Map params, String endpoint) {
    // Future<Map> completion; // <= if you want to use a completer this should be
    Completer<Map> completion = new Completer<Map>()

    switch (type) {
      case NetworkingRequestType.GET:
        // completion = _makeGetRequest(endpoint, params); // <= this would change to
        _makeGetRequest(endpoint, params).then((result) => completion.complete(result));

        break;

      case NetworkingRequestType.POST:
        // completion.complete({});
        _makePostRequest(endpoint, params).then((result) => completion.complete(result));
        break;
    }

    return completion.future;
  }

但对于此用例,您可能不需要使用 Completer

代码在不使用 Completer 的情况下看起来像:

Future<Map> makeRequest(NetworkingRequestType type, Map params, String endpoint) {

    switch (type) {
      case NetworkingRequestType.GET:
        return _makeGetRequest(endpoint, params);

        break;

      case NetworkingRequestType.POST:
        // return new Future.value({}); // or whatever you want to do here 
        return _makePostRequest(endpoint, params);
        break;
    }
  }

注意:代码未经测试。