Цикл Dart For Loop завершается до завершения асинхронной функции - PullRequest
0 голосов
/ 19 июня 2019

Я загружаю изображения по многочастному запросу по одному на сервер.Каждый раз, когда я отправляю изображение, я слушаю ответ на сообщение об успехе.

Если возвращается JSON["status"] == "Success", я соответствующим образом обновляю свою локальную базу данных, чтобы показать, что это конкретное изображение синхронизировано.Как только это изображение обновляется локально, я увеличиваю счетчик успехов на 1.

В конце цикла for в insertImageApi я возвращаю сообщение об успешном завершении, включая число успешно загруженных изображений.

Я успешно загружаю все изображения на сервер, но без моего взлома функция возвращает одно изображение меньше ожидаемого.(например, 5 из 6)

Я попытался включить задержку в 3 секунды, чтобы предоставить функции время для добавления последнего приращения успеха, но это не работает.

В настоящее время у меня есть троичный оператор в операторе возврата, который возвращает 0, если успехи == 0, в противном случае возвращает успех + 1, чтобы компенсировать последнее пропущенное приращение.

Я даже пытался увеличить успех до асинхронной функции UpdateImageDbApi.Я не совсем уверен, как мне не хватает этого последнего приращения.Я не вижу, как я мог бы извлечь из этого цикла for слишком рано, поскольку у меня есть функции ожидания везде ...

_handleApiResponse(var response, SafeguardImage image) async {
    var decodedResponse = json.decode(response);

    if (decodedResponse["status"] == "Success") {
      image.isSynced = 1;
      try {
        successes++; //HACK
        await UpdateImageDbApi().updateImage(image);

      } catch (e) {
        print('failed to update image row in db: ' + e.toString());
      }
    } else if (decodedResponse["status"] == "error") {
      try {
        SafeguardOrder order =
            await QueryOrderDbApi().queryOrder(image.orderId);
        order.isSyncable = 0;
        try {
          var result = await UpdateOrderDbApi().updateOrder(order);
          print("set order #${order.orderId} syncable to 0. result =" +
              result.toString());
        } catch (e) {
          print('unable to update order #${order.orderId} on db: ' +
              e.toString());
        }
      } catch (e) {
        print("unable to query database for images order id: " + e.toString());
      }
    }
  }

  Future<Map<String, dynamic>> insertImageAPI(
      List<SafeguardImage> images) async {

    var start = DateTime.now().millisecondsSinceEpoch;

    for (var image in images) {
      print(image.imageUrl);

      http.MultipartRequest request = await _createMultipartRequest(image);
      print(request.toString());
      try {
        var response = await request.send().timeout(Duration(seconds: 20));
        response.stream.transform(utf8.decoder).listen(
          (response) async {
            print(response.toString());
            await _handleApiResponse(response, image);
          },
        );
      } catch (e) {
        print(e.toString());
        return {
          "error":
              "there was a network error. please try again when you have service"
        };
      }
    }
    Future.delayed(Duration(seconds: 3)); //HACK
    var end = DateTime.now().millisecondsSinceEpoch;
    double duration = (end - start) / 1000;
    print(
        "post images complete: $successes sent. \n it took $duration seconds");
    return {
      "successes": successes == 0 ? 0 : successes + 1, //HACK
      "total_attempted": images.length,
      "duration": duration
    };
  }

Я пометил три хака комментариями.

...