import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() async {
print('start api');
for (var i = 1; i < 4; i ) {
print(unawaited(fetchApi(i)));
}
print('end api');
}
Future<String> fetchApi(int idNum) async {
final url = Uri.parse('https://jsonplaceholder.typicode.com/albums/$idNum');
final response = await http.get(url);
final jsonData = jsonDecode(response.body);
return jsonData['title'];
}
Based on documentation, i should just import async package and use unawaited().
However, i noticed that the unawaited() only take Future.
How to make this code works? thanks.
**The idea is to allow the next code in line triggered while http.get still doing its job. or should i move to Stream?
fetchApi() need to return string instead of void.
CodePudding user response:
Unawaited is used as a fire and forget method. So you can't do anything with it's response because it will continue in the code once the first await has been triggered.
To execute your fetch api do the following:
unawaited(fetchApi(i));
If you only want to log the string you can do it in your fetchApi function:
Future<String> fetchApi(int idNum) async {
final url = Uri.parse('https://jsonplaceholder.typicode.com/albums/$idNum');
final response = await http.get(url);
final jsonData = jsonDecode(response.body);
// Log the title
print(jsonData['title']);
return jsonData['title'];
}
But if you want to do something else with your string, use another method and fire and forget that one:
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() async {
print('start api');
for (var i = 1; i < 4; i ) {
unawaited(startSomething(i));
}
print('end api');
}
Future<void> startSomething(int idNum) async {
final result = await fetchApi(idNum);
print(result);
}
Future<String> fetchApi(int idNum) async {
final url = Uri.parse('https://jsonplaceholder.typicode.com/albums/$idNum');
final response = await http.get(url);
final jsonData = jsonDecode(response.body);
return jsonData['title'];
}
In both my examples, the output will be the following:
start api
end api
sunt qui excepturi placeat culpa
omnis laborum odio
quidem molestiae enim
CodePudding user response:
If you want to wait for async
function you can use await
before it, but if you don't want to wait for it and let other code runs you don't need any thing, so your code should looks like this:
void main() {
print('start api');
for (var i = 1; i < 4; i ) {
print(fetchApi(i));
}
print('end api');
}
but this won't give you what you want. you need to use Stream
like this:
Stream<String> checkConnectionStream() async* {
for (var i = 1; i < 4; i ) {
var asdasd = fetchApi(i);
print(await asdasd);
yield* Stream.fromFuture(asdasd);
}
}
CodePudding user response:
unawaited
is for use when you don't care about when the Future
completes. However, you do want to wait for the Future
complete so that you can call print
on its result.
In your case, you could explicitly use Future.then
. (Normally you should avoid Future.then
in favor of async
/await
, but this is a case where using Future.then
is a bit more straightforward.) Future.then
itself returns a Future
, so you can use unawaited
on that:
void main() async {
print('start api');
for (var i = 1; i < 4; i ) {
unawaited(fetchApi(i).then(print));
}
print('end api');
}
That said, I think it'd be even better to wait until all of your Future
s complete before claiming that you're done and returning from main
. For that, use Future.wait
:
void main() async {
print('start api');
await Future.wait([
fetchApi(i).then(print),
]);
print('end api');
}
The above code won't print 'end api'
until after all Future
s complete.