run_once 1.0.7+3 copy "run_once: ^1.0.7+3" to clipboard
run_once: ^1.0.7+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 a little exercise, but imagine a Flutter StatefulWidget with its build that you cannot rely on being called only when you yourself 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.

Worth a mention; there also is the AsyncMemoizer.runOnce for async functions from package:async but that one isn't aware of the call stack and works internally in a much simpler manner.

Usage #

Pure dart example;

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));
  }
}

Flutter with a StatefulWidget example;

import 'package:run_once/run_once.dart';

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

        return Placeholder();
      },
    );
  }  
}

Disclaimer #

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

1
likes
160
pub points
33%
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

Documentation

API reference

License

MIT (license)

More

Packages that depend on run_once