Flutter中的節流與防抖

Flutter中的節流與防抖

背景async

在一些計算較爲複雜、操做較爲耗時或者操做爲引發頁面重繪的場景,若是事件觸發的頻率毫無限制,除了帶來性能上的負擔,還會致使糟糕的用戶體驗。如:根據輸入框輸入的內容向服務端查詢相關文章,用戶屢次點擊收藏按鈕……ide

防抖(debounce)函數

在觸發事件時,不當即執行目標操做,而是給出一個延遲的時間,在該時間範圍內若是再次觸發了事件,則重置延遲時間,直到延遲時間結束纔會執行目標操做。性能

示例spa

如設定延遲時間爲500ms,code

  • 若是在500ms內沒有再次觸發事件,則執行目標操做
  • 若是在500ms內再次觸發了事件,則重置延遲時間,從新開始500ms的延遲,直到500ms結束執行目標操做

效果事件

連續點擊收藏按鈕,中止點擊時纔會執行」收藏/取消收藏「操做,只會執行一次」收藏/取消收藏「操做get

imageit

示例代碼io

 

// debounce.dart

import 'dart:async';

/// 函數防抖
///
/// [func]: 要執行的方法
/// [delay]: 要遲延的時長
Function debounce(
  Function func, [
  Duration delay = const Duration(milliseconds: 2000),
]) {
  Timer timer;
  Function target = () {
    if (timer?.isActive ?? false) {
      timer?.cancel();
    }
    timer = Timer(delay, () {
      func?.call();
    });
  };
  return target;
}

 

// debounce_page.dart

  Text(
    '$_count',
    style: Theme.of(context).textTheme.display1,
  ),
  Center(
    child: RaisedButton.icon(
      icon: Icon(Icons.add),
      label: Text('防抖'),
      onPressed: debounce(() {
        if (!mounted) {
          return;
        }
        setState(() {
          _count++;
        });
      }),
    ),
  ),

節流(throttle)

在觸發事件時,當即執行目標操做,同時給出一個延遲的時間,在該時間範圍內若是再次觸發了事件,該次事件會被忽略,直到超過該時間範圍後觸發事件纔會被處理。

示例

如設定延遲時間爲500ms,

  • 若是在500ms內再次觸發事件,該事件會被忽略
  • 若是500ms延遲結束,則事件不會被忽略,觸發事件會當即執行目標操做,並再次開啓500ms延遲

效果

連續點擊收藏按鈕,在第一次點擊時會當即執行」收藏/取消收藏「操做,在本次操做執行完成前的屢次點擊會被忽略,只會執行一次」收藏/取消收藏「操做。

image

示例代碼

 

// throttle.dart

import 'dart:async';

/// 函數節流
///
/// [func]: 要執行的方法
Function throttle(
  Future Function() func,
) {
  if (func == null) {
    return func;
  }
  bool enable = true;
  Function target = () {
    if (enable == true) {
      enable = false;
      func().then((_) {
        enable = true;
      });
    }
  };
  return target;
}

 

// throttle_page.dart
Text(
  '$_count',
  style: Theme.of(context).textTheme.display1,
),
Center(
  child: RaisedButton.icon(
    icon: Icon(Icons.add),
    label: Text('節流,耗時操做2s'),
    onPressed: throttle(() async {
      await Future.delayed(Duration(milliseconds: 2000));
      if (!mounted) {
        return;
      }
      setState(() {
        _count++;
      });
    }),
  ),
),
Divider(
  height: 8,
),
Text(
  '$_count3',
  style: Theme.of(context).textTheme.display1,
),
Center(
  child: RaisedButton.icon(
    icon: Icon(Icons.add),
    label: Text('不節流,耗時操做2s'),
    onPressed: () async {
      await Future.delayed(Duration(milliseconds: 2000));
      if (!mounted) {
        return;
      }
      setState(() {
        _count3++;
      });
    },
  ),
),

做者:xiaoxiami003 連接:https://www.jianshu.com/p/2b70ef340e82 來源:簡書 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

相關文章
相關標籤/搜索