如何在 Dart 的一个界面中结合传统和基于未来的 API?

How to combine traditional and Future-based API in one interface in Dart?

我想像在浏览器中一样在桌面上解析二进制文件(来自一些旧游戏)。 所以,我应该使用抽象 class,它可以从字节数组中读取二进制数据:

abstract class BinData {

  int readByte();

  String readNullString(){
    var buffer = new StringBuffer();
    int char;

    do {
      char = readByte();
      if (char == 0){
        break;
      }
      buffer.writeCharCode(char);
    } while(true);

    return buffer.toString();
  }

}

现在我可以实现我的解析器了。例如:

class Parser {
  BinData _data;

  void load(BinData data){
     ...
  }
}

对于桌面控制台应用程序,我使用 dart:io RandomAccessFile:

class FileBinData extends BinData {
  RandomAccessFile _file;

  FileBinData.from(RandomAccessFile file){
    this._file = file;
  }

  int readByte(){
    return this._file.readByteSync();
  }
}

对于 Web 应用程序,我必须使用 dart:html FileReader。但是,这个 class 只有基于 Future 的 API,与我的界面不兼容:

class WebFileBinData extends BinData {
  File _file;
  int _position = 0;

  WebFileBinData.from(File file){
    this._file = file;
  }

  int readByte(){
    Blob blob = _file.slice(_position, _position + 1); 

    FileReader reader = new FileReader();

    var future = reader.onLoad.map((e)=>reader.result).first
        .then((e) { ... });
    reader.readAsArrayBuffer(blob);

    ...
  }  
}

我该如何解决?

您的 readByte() 应该 return Future<int> 而不是 int。您可以从 function/method return Future 即使它不执行任何异步操作 (return new Future.value(5);) 但您不能 return int(或任何非 Future 值)来自执行异步操作的函数,至少当异步操作的结果应该 returned 时不会。

您还需要确保连接所有异步调用。

Future<int> readByte(){
  return reader.onLoad.map((e)=>reader.result).first
    .then((e) { 
      ... 
      return reader.readAsArrayBuffer(blob);
    });

** readNullString

  Future<String> readNullString() {
    var buffer = new StringBuffer();
    int char;

    return Future.doWhile(() {
      return readByte().then((char) {
        if (char == 0) {
          return false; // end doWhile
        }
        buffer.writeCharCode(char);
        return true; // continue doWhile
      });
    }).then((_) => buffer.toString()); // return function result 
  }