Обратный вызов, назначенный моему объекту Compler.future, не вызывается, когда я завершаю завершение после сетевого вызова

Я новичок в Dart и имею опыт работы с iOS, поэтому я могу неправильно использовать язык, что приводит к тому, что мой код не работает должным образом, но я также не могу найти решение в Интернете и подумал, что задам его здесь, если кто-то еще испытал это и починил это.

Итак, что я пытаюсь сделать, так это заставить фабрику моделей создать источник данных, в котором вы передаете тип запроса (GET или POST), передаете конечную точку и некоторые параметры. Затем он вернет вас в будущее, в котором вы прослушиваете вызов then(), который вызывается, когда сетевой запрос успешен/не пройден. Код, который у меня есть в настоящее время, работает до момента, когда я вызываю завершение.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);
  }
}

person ApperleyA    schedule 15.01.2015    source источник
comment
Вы возвращаете completion.future, но completion — это Future, а не Completer?   -  person lrn    schedule 15.01.2015
comment
Это я ошибся при редактировании поста   -  person ApperleyA    schedule 15.01.2015


Ответы (2)


Я не вижу ничего плохого в этом коде, за исключением того, что он не распространяет ошибки. Он должен работать. Если вызывается completion.complete, то должен завершиться completion.future, убедитесь, что completion.complete действительно вызывается (например, проверьте, были ли какие-либо сетевые ошибки на консоли, проверьте вкладку «Сеть» в DevTools, чтобы увидеть запрос/ответ).

В целом, я бы рекомендовал избегать явного использования завершителей. Просто используйте будущее, возвращаемое 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);
  }
person Vyacheslav Egorov    schedule 15.01.2015
comment
Эй, чувак, спасибо, что так быстро прокомментировал. Также спасибо за совет Ури, это гораздо более чистый способ сделать это. Но насколько мой код работает, это не так. Не знаю, почему. Будущее из .then(JSON.decode) возвращается, и я прикрепляю к нему then() еще раз в Фабрике моделей, но не играю в кости. Таким образом, теоретически выполнение then() должно быть HTTP Request Return String-> JSON.decode анализирует его-> я занимаюсь созданием моделей, если все работает. Я вижу, что HTTP-запрос возвращает 200 ok с моего сервера. - person ApperleyA; 15.01.2015
comment
@ApperleyA это странно. Я проверил код, и он работает dartlab.org/#9d14391454bf11f96e01 [нижний правый кадр занимает некоторое время, чтобы load, потому что он компилируется в JS прямо в браузере]. Также, как указано выше @lrn, в вашей версии кода вам нужно вернуть completion, а не completion.future. Вы получите NoSuchMethod ошибку в этой строке. - person Vyacheslav Egorov; 15.01.2015
comment
Я заставил его работать ... не знаю, как, но он начал работать сегодня. Спасибо за просмотр моего кода и помощь, которую вы оказали. - person ApperleyA; 17.01.2015

Ваш код выглядит как смесь использования 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;
    }
  }

Внимание: код не проверен.

person Günter Zöchbauer    schedule 15.01.2015