skip to Main Content

I have a requirement that my flutter app should not call multiple api
within same timestamp/second. i am working with a IoT device which has
its own server and the requirement is it cannot handle multiple api
calls in a second and from app there are multiple api calls as user
can do many actions in app and we don’t have the control over it. How
can we achieve this ? i tried using delays/Timer but its not working.
as expected

2

Answers


  1. One way to ensure that only one API call is made per second and no other API calls are made during that second in a Flutter app is to use a Debouncer.

    debouncer.dart

    import 'dart:async';
    
    class Debouncer {
      final Duration delay;
      Timer _timer;
    
      Debouncer({this.delay});
    
      void call(Function action) {
        _timer?.cancel();
        _timer = Timer(delay, action);
      }
    }
    

    and you can use this debouncer by creating an instance of it.
    Debouncer debouncer = Debouncer(delay: Duration(seconds: 1));
    Then, whenever you want to make an API call, call the Debouncer’s call method and pass in a function that makes the API call:

    debouncer(() {
      // Make API call here
    });
    
    Login or Signup to reply.
  2. If you’re using Dio package, I suggest adding a custom Interceptor that adds all requests to a queue and then applies the desired delay when processing them.

    import 'package:dio/dio.dart';
    
    
    class QueueInterceptor extends Interceptor {
      @override
      void onRequest(
          RequestOptions options, RequestInterceptorHandler handler) async {
        _requestQueue.add(() => super.onRequest(options, handler));
        _startQueueHandler();
        
      }
    }
    
    List<Function> _requestQueue = [];
    bool _busy = false;
    
    void _startQueueHandler() async {
      if (_busy) {
        print('queue: already processing requests');
        return;
      }
      _busy = true;
      while (_requestQueue.isNotEmpty) {
        print('queue: processing request...');
        final request = _requestQueue.removeAt(0);
        request();
        await Future.delayed(const Duration(seconds: 1));
      }
      print('queue: done');
      _busy = false;
    }
    
    

    Then add the interceptor to the Dio instance:

    _dio.interceptors.add(QueueInterceptor());
    

    Note that this Interceptor does not wait for the request to finish, so the delay is only between request firing. You can do that by overriding onResponse if needed.

    If you’re using http package directly, you can achieve the same result with a custom http client.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search