dart 中的节流函数执行

Posted

技术标签:

【中文标题】dart 中的节流函数执行【英文标题】:Throttle function execution in dart 【发布时间】:2019-04-05 10:14:16 【问题描述】:

Dart 有没有办法像这样限制函数执行

Observable.throttle(myFunction,2000);

【问题讨论】:

thottledebounce from github.com/ReactiveX/rxdart 应该提供。 medium.com/fantageek/… 可能是相关的。 我不确定如何将这些信息与我所拥有的信息结合起来,听按钮是否对颤振有效? 在 Dart 中,要重复调用的函数通常是 Stream 上的侦听器 - 你在这里有 Stream 并且你试图限制传递给 @ 的函数987654330@?如果是这种情况,我们应该将其视为限制流而不是函数。为此使用values.transform(throttle(Duration(seconds: 2))).listen(myFunction)。 pub.dartlang.org/packages/stream_transform 如果这不是 Stream 侦听器,您能否详细说明用例?你需要Function 可以作为参数传递吗? 我想限制函数执行,例如假设有一个按钮将向 api 发送请求,我希望该按钮始终可点击,但每次调用 1 次都会限制 api 调用例如 1 分钟,因此用户可以随意点击,但我每分钟只会发送一个请求。 您可以使用 StreamController 将函数调用转换为 Stream。 Mayberxdart Observable 提供了一些开箱即用的东西来做到这一点。 【参考方案1】:

使用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);

【讨论】:

【参考方案2】:
// 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");
    );
  );

【讨论】:

static int lastActionTime; 所以,如果你使用Throttler 类的多个实例,它们都将共享相同的lastActionTime 你是对的。我犯了一个错误。我顺便编辑一下答案。【参考方案3】:

按照 Günter Zöchbauer 的思路,您可以使用 StreamController 将函数调用转换为 Stream。举例来说,假设myFunction 有一个int 返回值和一个int 参数。

import 'package:rxdart/rxdart.dart';

// This is just a setup for the example
Stream<int> timedMyFunction(Duration interval) 
  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);

【讨论】:

【参考方案4】:
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();

【讨论】:

以上是关于dart 中的节流函数执行的主要内容,如果未能解决你的问题,请参考以下文章

函数防抖与函数节流

防抖与节流

等待异步函数在 dart 中无法正确执行

函数节流和函数去抖

节流函数-throttle

JavaScript函数节流