Home > Blockchain >  How to properly use unawaited in dart?
How to properly use unawaited in dart?

Time:01-15

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 Futures 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 Futures complete.

  • Related