坏状态:Stream已经收听了Flutter错误

时间:2018-03-23 10:18:57

标签: ios dart flutter

我打电话给api。发送请求后,我收到了一个流式响应。但我无法解析响应并将其转换为String / JSON。这就是我打电话给api的地方。

static Future<String> callDeviceListFetchApi() async {
Completer completer = new Completer();
String jsonResponse;
String url = Constants.BASE_URL + Constants.DEVICE_REGISTER_URL;
var client = new http.Client();
var request = new http.Request('GET', Uri.parse(url));
request.headers[HttpHeaders.CONTENT_TYPE] = 'application/json';
request.headers[HttpHeaders.AUTHORIZATION] = '<auth code>';
await client.send(request).then((response) {
  response.stream.bytesToString().then((value) {
    print(value.toString());
    jsonResponse = value.toString();
    completer.complete(jsonResponse);
  });
}).catchError((error) {
  print(error.toString());
});
return completer.future;
}

我收到错误, Bad state: Stream has already been listened to颤动错误。知道为什么会这样吗?

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。我认为你对Async和Futures如何在飞镖中工作有一点误解 - 你应该重新阅读docs和本教程(part 1part 2)。

基本上,问题是你从异步函数返回'Future'。如果从异步函数返回未来,它就会出现问题(我不知道分析器为什么不能捕获它)。

Future<String> callDeviceListFetchApi() async {
  Completer completer = new Completer();
  String url = "<url>";
  var client = new http.Client();
  var request = new http.Request('GET', Uri.parse(url));
  request.headers[HttpHeaders.CONTENT_TYPE] = 'application/json';
  request.headers[HttpHeaders.AUTHORIZATION] =
      '<auth string>';
  var response = await client.send(request);
  String jsonResponse;
  try {
    var value = await response.stream.bytesToString();
    print(value.toString());
    jsonResponse = value.toString();
  } catch (error) {
    print(error.toString());
  }
  return completer.complete(jsonResponse);
}

或者不是异步:

Future<String> callDeviceListFetchApiNotAsync() {
  String url = "<url>";
  var client = new http.Client();
  var request = new http.Request('GET', Uri.parse(url));
  request.headers[HttpHeaders.CONTENT_TYPE] = 'application/json';
  request.headers[HttpHeaders.AUTHORIZATION] =
      '<auth string>';
  Completer completer = new Completer();

  return client.send(request).then((response) {
    return response.stream.bytesToString();
  }).then((value) {
    print(value.toString());
    return value.toString();
  }).catchError((error) {
    print(error.toString());
    // if you use catchError, whatever you return from it
    // is the value you'll get wherever you resolve the future.
    return null;
  });
}

但除非你试图做一些我没有看到的事情,否则有一种更简单的方法(假设你要做的就是从服务器获取一个字符串):

Future<String> getList() async {
  var response = await http.get("<url>", headers: {
    HttpHeaders.CONTENT_TYPE: 'application/json', 
    HttpHeaders.AUTHORIZATION: '<auth string>',
  });
  if (response.statusCode == 200) {
    return response.body;
  } else {
    throw Error();
  }
}