如何用Dart语言将Future <List <Map>转换为List <Map>?

wat*_*man 10 dart flutter

我用dart语言编写了一个问题.如何将Future转换为正常List?在我的程序中,我需要从web继续下一步的结果,我不知道该怎么做.在我的例子中,我需要将变量"data"的值作为List返回.

class _MyAppState extends State<MyApp> {
    static List getList() {
    var url = "http://watcherman.cn/web/json.php";
    var data;
    HttpClient client = new HttpClient();
    client.getUrl(Uri.parse(url))
      .then((HttpClientRequest request) => request.close())
    .then((HttpClientResponse response) {
      response.transform(UTF8.decoder).listen((contents) {
        String jsonContent = contents.toString();
        data = JSON.decode(jsonContent);
      });
    });
    return data;
  }
}
Run Code Online (Sandbox Code Playgroud)

但似乎没有执行网络部分.扑动代码部分似乎无法接受未来.

class _MyAppState extends State<MyApp> {
  static List content = getList();
  @override
  Widget build(BuildContext context) {
    return new Container(
        child: new ListView.builder(
            scrollDirection: Axis.vertical,
            padding: new EdgeInsets.all(6.0),
            itemCount: content.length,
            itemBuilder: (BuildContext context, int index) {
              return new Container(
                  alignment: FractionalOffset.center,
                  margin: new EdgeInsets.only(bottom: 6.0),
                  padding: new EdgeInsets.all(6.0),
                  color: Colors.blueGrey,
                  child: new Text(content[index]["title"])
              );
            }
        )
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Col*_*son 15

你应该重写你的getList方法来返回一个Future<List>.可以通过一系列then()调用来实现这一点,但使用async/的await可读性更高的IMO .

一旦有了返回a的方法,Future<List>就可以使用FutureBuilder构建依赖于异步计算结果的树.

截图

import 'package:flutter/material.dart';
import 'dart:io';
import 'dart:convert';
import 'dart:async';

void main() {
  runApp(new MaterialApp(
    home: new MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  State createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {

  static Future<List> getList() async {
    var url = "http://watcherman.cn/web/json.php";
    HttpClient client = new HttpClient();
    HttpClientRequest request = await client.getUrl(Uri.parse(url));
    HttpClientResponse response = await request.close();
    return response.transform(UTF8.decoder).transform(JSON.decoder).toList();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Futures Demo'),
      ),
      body: new FutureBuilder(
        future: getList(),
        builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
          if (!snapshot.hasData)
            return new Container();
          List content = snapshot.data[0];
          return new ListView.builder(
            scrollDirection: Axis.vertical,
            padding: new EdgeInsets.all(6.0),
            itemCount: content.length,
            itemBuilder: (BuildContext context, int index) {
              return new Container(
                alignment: FractionalOffset.center,
                margin: new EdgeInsets.only(bottom: 6.0),
                padding: new EdgeInsets.all(6.0),
                color: Colors.blueGrey,
                child: new Text('${content[index]['title']}'),
              );
            },
          );
        }
      )
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


lrn*_*lrn 5

您无法摆脱异步。

在Dart中,函数返回一个值或一个Future。当结果还没有准备好时,当函数返回时,它将返回将来,它将仅在以后使用。

这意味着,如果您只拥有a Future并且现在想要该值,则您将陷入困境,因为该值还不存在。您无法返回List now,因为,现在Future<List>没有列表,只有稍后列表。

因此,您必须等待未来,var data = await client.getUrl(...)...这意味着您的函数也必须是异步的。因此,使getList函数返回a Future<List>而不是a List,因为这就是它所能做的。

Dart不支持的替代方法是阻塞操作,该操作将停止执行直到有可用值,然后再继续正常执行。在单线程语言(例如Dart和JavaScript,Dart必须编译为该语言)中,这是一个问题,因为阻塞意味着什么都不会发生,并且UI变得无响应。

因此,如果您的结果取决于未来的价值,那么您的函数也必须是异步的,并作为未来返回自己的结果。