Flutter, как прервать предотвращение запроса с помощью http-пакета

У меня есть текстовое поле для поиска городов. Когда я набираю символ, на сервер отправляется запрос (API). Когда я ввожу любой символ. Мне нужно отменить предыдущий запрос, который находится на рассмотрении. Помогите пожалуйста уважаемые профессионалы, Спасибо). Я не могу отменить свой предыдущий запрос

это httpService

Future<http.Response> httpGetPublic(path) async {
  try {
    var response = await http.get(Uri.parse(path), headers: {
      HttpHeaders.contentTypeHeader: "application/json",
      HttpHeaders.hostHeader: API.hostname,
      HttpHeaders.cacheControlHeader: "no-cache",
      HttpHeaders.acceptHeader: "application/json",
      HttpHeaders.acceptEncodingHeader: "gzip, deflate, br",
    }).timeout(
      const Duration(seconds: 30),
      onTimeout: () {
        return http.Response('Connection Timeout', 408);
      },
    );

    return response;

  } catch (error) {    
    return http.Response('{"error":"${error.toString()}"}', 500);
  }
}

этот метод получения данных

void fetchData(String query) async {
  cities.clear();
  _isLoading.value = true;
  final response = await httpGetPublic("${API.cities}?name=$query");
  try {
    Iterable data = jsonDecode(utf8.decode(response.bodyBytes));

    if (response.statusCode == 200) {
      List<FlightCitiesModel> res = List<FlightCitiesModel>.from(
          data.map((model) => FlightCitiesModel.fromJson(model)));

      cities.addAll(res);
    } else {
      if (response.statusCode < 430) {
         snackBarResponseError(responseData);
      }
    }
  } catch (error) {
    debugPrint("ERROR ====>");
    debugPrint(error.toString());
  }

  _isLoading.value = false;
}

это мое текстовое поле поиска

TextField(
  autofocus: true,
  decoration: InputDecoration(
    isDense: true,
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(8),
    ),
    suffixIcon: const Icon(
      Icons.search,
      size: 26,
    ),
  ),
  onChanged: (String value) {
    if (value.length > 1) {
      citiesController.setLoading();
    }
    if (_timer?.isActive ?? false) _timer!.cancel();
    _timer = Timer(const Duration(milliseconds: 150), () {
      citiesController.fetchData(value);
    });
  },
);
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете добиться этого, используя функцию CancelToken пакета http вместе с пакетом dio:

  1. Убедитесь, что у вас есть необходимый импорт для http и dart:async.
import 'dart:async';
import 'package:http/http.dart' as http;
  1. Вам нужно будет сохранить ссылку на текущий запрос и отменить его при запуске нового.
// Create a variable to hold the current request
http.CancelToken? _cancelToken;

// Modify your existing function to accept a cancel token
Future<http.Response> httpGetPublic(String path) async {
  // Cancel the previous request if it exists
  _cancelToken?.cancel();

  // Create a new cancel token for this request
  _cancelToken = http.CancelToken();

  try {
    var response = await http.get(
      Uri.parse(path),
      headers: {
        HttpHeaders.contentTypeHeader: "application/json",
        HttpHeaders.hostHeader: API.hostname,
        HttpHeaders.cacheControlHeader: "no-cache",
        HttpHeaders.acceptHeader: "application/json",
        HttpHeaders.acceptEncodingHeader: "gzip, deflate, br",
      },
      // Pass the cancel token to the request
      cancelToken: _cancelToken,
    ).timeout(
      const Duration(seconds: 30),
      onTimeout: () {
        // Handle timeout
        return http.Response('Connection Timeout', 408);
      },
    );
    return response;
  } catch (error) {
    return http.Response('{"error":"${error.toString()}"}', 500);
  }
}

Теперь, когда вы вызываете этот метод, он сначала отменяет существующий запрос, а затем вызывает новый.

Другие вопросы по теме