run_once 1.0.3 copy "run_once: ^1.0.3" to clipboard
run_once: ^1.0.3 copied to clipboard

An extremely simple library for running 'things' exactly once. No matter how many times that 'thing' is called.

run_once #

An extremely simple library for running 'things' exactly once. No matter how many times that 'thing' is called.

How does it work ? #

Well it's very simple. We basically use the StackTrace.current and carefully use this to keep record on when a function has been called. It means that the call stack is basically used as a unique identifier for when and where a function has been called.

Rationale #

This library could be considered an anti-pattern in itself and as a little exercise, but imagine a Flutter StatefulWidget with its build that you cannot rely on being called only when YOU call setState. In this case you could use runOnce to run something once during this widget's lifetime no matter the times build was called.

/// This example uses the state_notifier package
class SomeWidget extends StatefulWidget {
  const SomeWidget({ super.key });
}

class _SomeWidgetState extends State<SomeWidget> {
  @override
  void dispose() {
    /// When this is called we clear the [runOnce] for this class alone.
    /// Then [runOnce] can run once again.
    runOnceDestroy();
    
    super.dispose();
  }
  
  @override
  Widget build(BuildContext context) {
    final state = context.watch<MyState>();
    return state.when(
      data: () => Placeholder(),
      loading: () {
        runOnce(() {
          Navigator.pushNamed(context, '/b'); // This is always only called once until [dispose] is called
        });

        return Placeholder();
      },
    );
  }  
}

Usage #

import 'package:run_once/run_once.dart';

void main() async {
  /// This will print 'called 1' exactly 1 time although
  /// we call this function 10 times.
  for (var i = 0; i < 10; i++) {
    runOnce(() {
      print('called 1');
    });
  }

  /// This will print 'called 2' exactly 2 times as the [runOnce] simply
  /// isn't called in the same spot.
  runOnce(() {
    print('called 2');
  });
  runOnce(() {
    print('called 2');
  });

  /// This will print 'called 3' exactly 3 times although
  /// we call this function 15 times.
  /// Note the `forDuration` is exactly a [Duration] of 500 milliseconds.
  /// Using `forDuration` means for a duration of 500 milliseconds [runOnce]
  /// can only run once.
  /// So we loop 15 times in this loop and wait 100 milliseconds in each
  /// loop cycle; thus 'called 3' is printed exactly 3 times.
  for (var i = 0; i < 15; i++) {
    await Future.delayed(Duration(milliseconds: 100));

    runOnce(() {
      print('called 3');
    }, forDuration: Duration(milliseconds: 500));
  }
}

Disclaimer #

This library isn't really tested very comprehensively at all. So it might not work in every use case.

1
likes
0
pub points
53%
popularity

Publisher

unverified uploader

An extremely simple library for running 'things' exactly once. No matter how many times that 'thing' is called.

Repository (GitLab)
View/report issues

License

unknown (LICENSE)

More

Packages that depend on run_once