Skip to content

Prior work: Dart zones #78

@pschiffmann

Description

@pschiffmann

In Dart, you can use zones to achieve the same goal as you're going for with this proposal. Dart zones are not a 3rd party library, but are provided by the runtime - that means they work with async/await. I haven't seen them mentioned in the "prior arts" section, so I thought I'd mention them here. If you were aware of them already, kindly close this issue. :-)

Here is how you can translate the AsyncContext.Variable example to the Dart zone API:

import "dart:async";
import "dart:math";

var asyncVar = {};

main() {
  // Dart programs start in the `main`function, so I have moved the zone demo code to `main_`.
  runZoned(main_, zoneValues: {asyncVar: "top"});
}

main_() {
  randomTimeout().then((_) {
    print(Zone.current[asyncVar]); // => "top"

    runZoned(() async {
      print(Zone.current[asyncVar]); // => "A"
      await randomTimeout();
      print(Zone.current[asyncVar]); // => "A"
    }, zoneValues: {asyncVar: "A"});
  });

  runZoned(() async {
    print(Zone.current[asyncVar]); // => "B"
    await randomTimeout();
    print(Zone.current[asyncVar]); // => "B"
  }, zoneValues: {asyncVar: "B"});

  print(Zone.current[asyncVar]); // => "top"
}

randomTimeout() {
  return Future.delayed(Duration(milliseconds: Random().nextInt(1000)));
}

My two cents on the API: I personally prefer the Dart zone API design over the proposal for two reasons:

  1. In Dart, you don't have to create a Variable, you could just as well use any other value as a zone key. You can still have private variables, by using a module private object (i.e. the equivalent of const asyncVar = Symbol()) as key. But you can also use other objects as zone keys, which might be handy in certain situations.
  2. You can set multiple zone keys at once. For example if you have two variables asyncVar1 and asyncVar2 and you want to set values for both of them, with the current proposal, you'd have to write it like this, right? asyncVar1.run("A", () => asyncVar2.run("B", () => ...)). With the Dart zone API, you can do a single runZoned(..., { asyncVar1: "A", asyncVar2: "B" }) instead.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions