在Riverpod中侦听来自提供商的值的延迟



最小可复制代码:

StreamController<int> _streamController = StreamController();
final provider1 = StreamProvider<int?>((ref) {
return _streamController.stream.map((value) {
print('listener1()');
return value;
});
});
final provider2 = StreamProvider<int?>((ref) {
return ref.watch(provider1).maybeWhen(
orElse: () => Stream.value(null),
data: (value) {
print('listener2()');
return Stream.value(value);
},
);
});
class FooPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
ref.watch(provider2);
return Scaffold(
body: ElevatedButton(
onPressed: () async {
await _streamController.addStream(Stream.value(42));
print('Done');
},
child: Text('Button'),
),
);
}
}

当你按下按钮时,它打印:

I/flutter (15845): listener1()
I/flutter (15845): Done
I/flutter (15845): listener2()

但正确的顺序应该是:

I/flutter (15845): listener1()
I/flutter (15845): listener2()
I/flutter (15845): Done

那么,我该如何修复这个延迟呢?是谁造成的?

我像下面这样修改代码,只将firebase任务委托给add1()

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
void main() {
runApp(
const ProviderScope(child: MaterialApp(home: MyApp())),
);
}

final StreamController<int> streamController = StreamController.broadcast();
final provider1 = StreamProvider<int>((ref) {
return streamController.stream.map((e) {
print("provider1 : receive event");
return e;
});
});
final provider2 = StreamProvider<int>((ref) {
return ref.watch(provider1).maybeWhen(
orElse: () => Stream.value(-1),
data: (user) {
print('provider2 : value received from provider1');
return Stream.value(user);
},
);
});

class MyApp extends ConsumerStatefulWidget {
const MyApp({
Key? key,
}) : super(key: key);
@override
ConsumerState createState() => _MyAppState();
}
class _MyAppState extends ConsumerState<MyApp> {
Future<void> add1() async {
await Future.delayed(const Duration(seconds: 1));
streamController.add(1);
await Future.delayed(Duration.zero); // HERE!
}
@override
Widget build(BuildContext context) {
ref.watch(provider2);
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () async {
await add1();
print("button : clicked");
},
child: Text("click"),
),
),
);
}
}

add1()中可以看出,最后还有await Future.delayed(Duration.zero)。如果点击按钮,有两个结果。

provider1 : receive event
provider2 : value received from provider1
button : clicked

provider1 : receive event
button : clicked
provider2 : value received from provider1

但是如果这行被删除,你可以看到你想要的

provider1 : receive event
provider2 : value received from provider1
button : clicked

所以我认为原因是在逻辑firebase工作。

最新更新