flutter dart中的节流函数执行

9fkzdhlc  于 2022-11-30  发布在  Flutter
关注(0)|答案(4)|浏览(177)

Dart中是否有一种方法可以像这样限制函数的执行
Observable.throttle(myFunction,2000);

olmpazwi

olmpazwi1#

使用https://pub.dartlang.org/documentation/rxdart/latest/rx/Observable/throttle.html
因此,您在Dart 2中使用RxDart的示例是

final subject = new ReplaySubject<int>();
myCaller(Event event) {
  subject.add(event);
}
subject
  .throttle(Duration(seconds: 2))
  .listen(myHandler);
bxpogfeg

bxpogfeg2#

// you can run the code in dartpad: https://dartpad.dev/
typedef VoidCallback = dynamic Function();

class Throttler {
  Throttler({this.throttleGapInMillis});

  final int throttleGapInMillis;

  int lastActionTime;

  void run(VoidCallback action) {
    if (lastActionTime == null) {
      action();
      lastActionTime = DateTime.now().millisecondsSinceEpoch;
    } else {
      if (DateTime.now().millisecondsSinceEpoch - lastActionTime > (throttleGapInMillis ?? 500)) {
        action();
        lastActionTime = DateTime.now().millisecondsSinceEpoch;
      }
    }
  }
}

void main() {
  var throttler = Throttler();
  // var throttler = Throttler(throttleGapInMillis: 1000);
  throttler.run(() {
    print("will print");
  });
  throttler.run(() {
    print("will not print");
  });
  Future.delayed(Duration(milliseconds: 500), () {
    throttler.run(() {
      print("will print with delay");
    });
  });
}
nue99wik

nue99wik3#

import 'package:flutter/foundation.dart';
import 'dart:async';

// A simple class for throttling functions execution
class Throttler {
  @visibleForTesting
  final int milliseconds;

  @visibleForTesting
  Timer? timer;

  @visibleForTesting
  static const kDefaultDelay = 2000;

  Throttler({this.milliseconds = kDefaultDelay});

  void run(VoidCallback action) {
    if (timer?.isActive ?? false) return;

    timer?.cancel();
    action();
    timer = Timer(Duration(milliseconds: milliseconds), () {});
  }

  void dispose() {
    timer?.cancel();
  }
}

// How to use
void main() {
  var throttler = Throttler();

  throttler.run(() {
    print("will print");
  });
  throttler.run(() {
    print("will not print");
  });
  Future.delayed(const Duration(milliseconds: 2000), () {
    throttler.run(() {
      print("will print with delay");
    });
  });

  throttler.dispose();
}
shyt4zoc

shyt4zoc4#

按照君特·佐施鲍尔的思路,你可以使用StreamController将函数调用转换为Stream,为了便于举例,我们假设myFunction有一个int返回值和一个int参数。

import 'package:rxdart/rxdart.dart';

// This is just a setup for the example
Stream<int> timedMyFunction(Duration interval) {
  late StreamController<int> controller;
  Timer? timer;
  int counter = 0;

  void tick(_) {
    counter++;
    controller.add(myFunction(counter)); // Calling myFunction here
  }

  void startTimer() {
    timer = Timer.periodic(interval, tick);
  }

  void stopTimer() {
    if (timer != null) {
      timer?.cancel();
      timer = null;
    }
  }

  controller = StreamController<int>(
    onListen: startTimer,
    onPause: stopTimer,
    onResume: startTimer,
    onCancel: stopTimer,
  );

  return controller.stream;
}

// Setting up a stream firing twice a second of the values of myFunction
var rapidStream = timedMyFunction(const Duration(milliseconds: 500));

// Throttling the stream to once in every two seconds
var throttledStream = rapidStream.throttleTime(Duration(seconds: 2)).listen(myHandler);

注意:请注意throttleTime的额外参数。默认值为trailing=falseleading=true。如果您希望将最新样本保持在节流周期内,则您更希望使用trailing: trueleading: false

相关问题