2

このコードがどのように機能するかを理解するのを手伝ってください。そして、なぜそのように機能するのか。

例の変数resStream<Row>.

メソッドFuture<List>から戻りたい。processQueryResultこのコードは正常に機能し、正しい結果が得られます。

例 1

Future<List> processQueryResult(mysql.Results res) {
  List data = [];

  res.toList().then((List<mysql.Row> rows) {
    rows.forEach((mysql.Row row) {
      data.add({name: row.name, email: row.email});
    });
  });

  return new Future<List>(() {
    return data;
  });
}

結果dataには、必要なすべてのデータが含まれています。

しかし、教えてください、なぜコードのこの部分を移動すると

res.toList().then((List<mysql.Row> rows) {
  rows.forEach((mysql.Row row) {
    data.add({name: row.name, email: row.email});
  });
});

return new Future<List>(() {

  res.toList().then((List<mysql.Row> rows) {
    rows.forEach((mysql.Row row) {
      data.add({name: row.name, email: row.email});
    });
  });

  return data;

});

最後にコードの外観 (例 2 ):

Future<List> processQueryResult(mysql.Results res) {
  List data = [];      

  return new Future<List>(() {
    res.toList().then((List<mysql.Row> rows) {
      rows.forEach((mysql.Row row) {
       data.add({name: row.name, email: row.email});
      });
    });

    return data;
  });
}

その結果、空のリストが表示されます。

テストでは、次の関数を使用します。

testResult() {

  mysql.Results res = ... // get results;
  processQueryResult(res).then((data) {
    print(data);
  })

}

Example 1processQueryResultのようなコードでは正しいデータが得られますが、Example 2のようなコードでは空のリストが得られます。processQueryResult

教えてください、なぜこれが起こっているのですか?

適切な記事またはドキュメントへのリンクを提供していただければ幸いです。

4

1 に答える 1

2
return new Future<List>(() {

  res.toList() // <== 1.) registers a future for later execution // <== 3.) execute `toList()`
    .then((List<mysql.Row> rows) {
    rows.forEach((mysql.Row row) { // <== 4.) execute rows.forEach
      data.add({name: row.name, email: row.email});
    });
  });

  return data; // <== 2.) return data

});

3.) 上記のコードを呼び出すコードがすべての同期実行を終了した後に実行されます

return new Future<List>(() {

  return res.toList() // <== returning the future keeps the async parts connected
                      // and one is executed after the other
    .then((List<mysql.Row> rows) {
      rows.forEach((mysql.Row row) { // <== 4.) execute rows.forEach
        data.add({name: row.name, email: row.email});
      });
    })
    .then((_) data);  // <== the same here, return data **after** the previous statements are finished
  });
});
于 2014-10-24T08:33:31.003 に答える