I have 2 functions. I want to run them one by one but while the first function is done, the second function must wait for 1-2 seconds. I tried Future.delayed for this but it did not work. It changes nothing.
void kartat(int tip, int deger, int mainid, List mycards) {
masadakicards.add(cardbank[mainid]);
print("kart atıldı");
rakipkartat(51);
}
void rakipkartat(int mainid) {
new Future.delayed(Duration(seconds: 1), () {
// deleayed code here
masadakicards.add(cardbank[mainid]);
print("ann");
});
}
A way that you can achieve this is by using await Future.delayed
make sure that your method is returns a Future
Future<void> start() async {
await foo();
await Future.delayed(Duration(seconds: 2));
await bar();
}
Future<void> foo() async {
print('foo started');
await Future.delayed(Duration(seconds: 1));
print('foo executed');
return;
}
Future<void> bar() async {
print('bar started');
await Future.delayed(Duration(seconds: 1));
print('bar executed');
return;
}
expected:
foo started
- waits 1 second -
foo executed
- waits 2 seconds -
bar started
- waits 1 second -
bar executed
Following your methods
Please note that the method that gets executed after the delay also needs to include async and await, otherwise the method will run synchronously and not await the Future.
Future<void> start() async {
foo();
}
void foo() {
Future.delayed(Duration(seconds: 2), () async {
// do something here
await Future.delayed(Duration(seconds: 1));
// do stuff
});
}
Not sure if your overall approach is appropriate (can't tell from this), however,
Future<void> rakipkartat(int mainid) async { should do.
I guess it would be better if you create both and the calling function as Future and then call the functions with await kartet(); await rakipkartat()
By the way, implementing my 1st paragraph also requests that the calling function is a Future or at least handles the call as a Future.
Related
There are some questions posted about uploading multiple files to Firebase, but all the solutions I came across use a forEach loop or something similar to upload one by one. However, if I'm uploading files that depend on each other (say, my app requires both of them to exist to function correctly), this could be an issue because one of the uploads could succeed and the other fail.
I thought there must be a way to do something similar to a batch write in Firestore but for uploading files in Firebase Storage.
Is there any way to do that or is the loop method the only way?
(I'm using Flutter, so if possible I would appreciate it if any code provided as an answer is written in Dart)
Well, you could use Future.wait() to upload your files simultaneously without waiting for any of them to complete before you begin other.
To explain further, I made the following code snippet, please follow along:
void main() {
Future.wait([
uploadImage1(),
uploadImage2(),
uploadImage3(),
]);
}
Future<void> uploadImage1() async {
await Future.delayed(Duration(seconds: 3), () {
print('1');
});
}
Future<void> uploadImage2() async {
throw Exception();
}
Future<void> uploadImage3() async {
await Future.delayed(Duration(seconds: 3), () {
print('3');
});
}
I made three async operations, and added them all to Future.wait list, so all are executed/triggered at the same time, doesn't matters if any of them fails. Try the code on dart pad and you will see the output appears at the same time, the output would look like:
1
3
: ExceptionError: Exception
On the other hand, if you want to wait for one operation to successfully finish, then you can use await on a method that returns Future, so it will wait until the operation is successfully completed.
void main() async {
await uploadImage1();
await uploadImage2();
await uploadImage3();
}
Future<void> uploadImage1() async {
await Future.delayed(Duration(seconds: 3), () {
print('1');
});
}
Future<void> uploadImage2() async {
throw Exception();
}
Future<void> uploadImage3() async {
await Future.delayed(Duration(seconds: 3), () {
print('3');
});
}
The output would be:
1
: ExceptionError: Exception
hello I want have to run two functions(Function1() and Function2()) and store value of these returns and run third function. But some time according to condition Function1() or Function2() or both not be run.
if(condition1){
await Function1();
}
if(condition2){
await Function2();
}
await Functon3();
I try as above but Function3() run simultaneously with Function1() or with Function2().
My Function1() code looks like following...
Future Function1() async {
apiService
.apiFileUpload()
.then((value) async {
///codes goes here
}).catchError((error) {
print('EEEE: ' + error.toString());
});
}
If anything not clear please let me know in the comment section.
Please do not use .then() in combination with async/await. It is technically possible, but it takes some skill to get it right, so why make it hard on yourself. Stick with one way of doing it, use either one or the other. You mixed it up and through a slight oversight, your Function1 does not actually wait on it's result. It just returns, with the function still running in the then block. So you await it, but that does not help.
Since you are using await already, stick with that and remove .then() from your repertoire for now:
Future Function1() async {
try {
final value = await apiService.apiFileUpload();
///codes goes here
} catch(error) {
print('EEEE: ' + error.toString());
}
}
You can use await
Future Function1() async {
try{
final value = await apiService
.apiFileUpload();
final value2 = await secondFuntion();
///add more and condition on values
} catch(e){
.....
}
}
from your question you need to tell the compiler to stop on particular task with await and avoid using then function it will never stop your compiler
your future fuction:
Future Function1() async {
apiService
.apiFileUpload()
.then((value) async {
///codes goes here
}).catchError((error) {
print('EEEE: ' + error.toString());
});
}
Modified Future func
Future Function1() async {
var result = await apiService.apiFileUpload();
if(result == success){
// code goes here
}else{
//you can show your error here
}
}
In C# I can use async and await to process tasks in parallel. I can kick off an asynchronous task, do other things, and finally await for the asynchronous task to complete.
var t = myFunctionAsync();
executeTask1();
executeTask2();
await t;
How can I do this in dart/flutter?
Reference: async-await
void main() async {
var t = myFunctionAsync();
executeTask1();
executeTask2();
await t;
}
Future<int> myFunctionAsync() async {
await Future.delayed(const Duration(seconds: 2));
return 2;
}
void executeTask1() {
// do something
}
void executeTask2() {
// do something
}
void someFunction () async{
executeTask1();
executeTask2();
await executeTask3();
}
I'm trying to write a test using FakeAsync but it seems to hang on my awaits. Here's a stripped down example:
test('danny', () async {
await FakeAsync().run((FakeAsync async) async {
print('1');
final a = Future<bool>.delayed(const Duration(seconds: 5))
.then((_) => print('Delayed future completed!'))
.then((_) => true);
print('2');
async.elapse(const Duration(seconds: 30));
// Tried all this too...
// async.flushMicrotasks();
// async.flushTimers();
// async.elapse(const Duration(seconds: 30));
// async.flushMicrotasks();
// async.flushTimers();
// async.elapseBlocking(const Duration(seconds: 30));
print('3');
await a;
print('4');
expect(1, 2);
});
});
This code outputs:
1
2
Delayed future completed!
3
// hangs and never prints '4'
The async.elapse call is allowing the future to be completed, but it still hangs on await a. Why?
This seems to occur because although the Future is completed, the await call requires the microtask queue to be processed in order to continue (but it can't, since nobody is calling async.elapse after the await).
As a workaround, contiually pumping the microstask queue while the function is running seems to work - for example calling this function in place of FakeAsync.run:
/// Runs a callback using FakeAsync.run while continually pumping the
/// microtask queue. This avoids a deadlock when tests `await` a Future
/// which queues a microtask that will not be processed unless the queue
/// is flushed.
Future<T> runFakeAsync<T>(Future<T> Function(FakeAsync time) f) async {
return FakeAsync().run((FakeAsync time) async {
bool pump = true;
final Future<T> future = f(time).whenComplete(() => pump = false);
while (pump) {
time.flushMicrotasks();
}
return future;
}) as Future<T>;
}
It seems that await does not work inside fakeAsync, so you are stuck with Future.then() and friends.
However you can very easily wait for all Futures to complete by calling time.elapse()and time.flushMicrotasks().
test('Completion', () {
fakeAsync((FakeAsync time) {
final future = Future(() => 42);
time.elapse(Duration.zero);
expect(future, completion(equals(42)));
time.flushMicrotasks();
});
});
Is it possible to call an async function inside dart:Stream.periodic function?
I tried to wrap my async function but it is not working, please see code below.
Stream.periodic(Duration(seconds: _pollingInterval), _checkConnectivity)
String _checkConnectivity(int x) async {
return await _connectionRepository.checkConnection();
}
Use asyncMap:
Stream<String> checkConnectionStream() async* {
yield* Stream.periodic(Duration(seconds: _pollingInterval), (_) {
return _connectionRepository.checkConnection();
}).asyncMap((event) async => await event);
}
I'm not too familiar with dart streams yet, but you should be able to simulate what you're trying to achieve like this:
final controller = StreamController<String>();
Timer timer;
controller.onListen = () {
timer = Timer.periodic(
_pollingInterval,
(timer) => _connectionRepository.checkConnection().then((data){
if(!controller.isClosed){
controller.add(data);
}
}),
);
};
controller.onCancel = () {
timer?.cancel();
}
return controller.stream;
The stream does not support pause and continue, though. If you want that you'd need to override the corresponding callbacks on the controller and start/stop the timer there.
Also, depending on the timing of checkConnection this can result in events in the stream being very different to _pollingInterval.