1
votes

The following leaves s null after the file read exits:

String s;
new File('etc.stk').readAsString().then((String contents) {
    s = contents;
});
// s is null here.

Is there a way to save (or clone) s, or am I compelled to use it only in the .then scope?

I have a few thousand lines of compiler/interpreter code that parses and runs the file contents, and would prefer not to have them all inside the new File scope.

EDIT

To provide more context, what I am trying to do is something like

new File('etc1.stk').readAsString()
    .then((String script) {     
      syntaxTree1 = buildTree(script);
    });
new File('etc2.stk').readAsString()
    .then((String script) {
      syntaxTree2 = buildTree(script);
    }); 

and have access to both syntaxTree1 and syntaxTree2 in subsequent code. I will wrap my mind around the Dart Way if I can.

1

1 Answers

3
votes

EDIT
(this code is tested)

import 'dart:async' as async;
import 'dart:io' as io;

void main(args) {
// approach1: inline
  async.Future.wait([
     new io.File('file1.txt').readAsString(),
     new io.File('file2.txt').readAsString()
  ]).then((values) {
    values.forEach(print);
  });

// approach2: load files in another function
  getFiles().then((values) {
    values.forEach(print);
  });
}

async.Future<List> getFiles() {
  return async.Future.wait([
     new io.File('file1.txt').readAsString(),
     new io.File('file2.txt').readAsString()
  ]);
}

output:

file1
file2

file1
file2

EDIT END

hint: the code is not tested

// s is null here

is because this line is executed before

s = contents

This code

new File('etc.stk').readAsString()

returns a future that is enlisted in the event queue and is executed when the actual 'thread' of execution is finished.

If you had provided more code I would have a better context for a proposed solution.
What you could do is

String s;
new File('etc.stk').readAsString().then((String contents) {
    s = contents;
}).then((_) {
// s is **NOT** null here.
});

or

//String s;
new File('etc.stk').readAsString().then((String contents) {
    //s = contents;
    someCallback(s)
});
// s is null here.

void someCallback(String s) {
  // s is **NOT** null here
}

or

Future<String> myReadAsString() {
  return new File('etc.stk').readAsString();
}

myReadAsString().then((s) {
  // s is **NOT** null here
}

see also:

and maybe