#asynchronous #flutter #future
#асинхронный #флаттер #будущее
Вопрос:
Чтобы меня не FutureBuilder
вызывали снова и снова (см. Это), у меня есть привычка вызывать мои futures, initState
и это всегда работало нормально, пока мне не пришлось использовать вложенные.
По сути, я хочу, чтобы второе будущее вызывалось только после connectionState
того, как станет 1 done
-м. Любая помощь?
Вот мой код для дальнейшего объяснения-
FutureBuilder(
future: _future1,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return snapshot.connectionState != ConnectionState.done
? CircularProgressIndicator()
: snapshot.data != 200
? SomeWidget()
: FutureBuilder(
future: _future2,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return snapshot?.connectionState == ConnectionState.done
? Text('')
: CircularProgressIndicator();
});
},
);
Итак, в принципе, я вообще не хочу, _future2
чтобы меня вызывали, если данные, полученные от _future1
, не равны 200. Другими словами, я хочу решить _future2
, следует ли вызывать или нет на основе результата _future1
.
Комментарии:
1. не могли бы вы подробнее рассказать. используете ли вы
AsyncMemoizer
, как описано в ссылке? добавление некоторого кода помогло бы.2. Я добавил код, чтобы объяснить больше, и нет, я не использую
AsyncMemoizer
. Должен ли я это делать?3. просто используйте one
FutureBuilder
— вам не нужны эти два вложенныхFutureBuilder
s — вместо этого вы должны использовать aFuture
, который завершается на основе ваших двух другихFuture
s4. Я вас не понял. Не могли бы вы объяснить подробнее? (Если возможно, с помощью кода.)
5. вам не нужно
Future.wait
, вам нужноexpensiveA() .then((aValue) => expensiveB()) .then((bValue) => expensiveC()) .then((cValue) => doSomethingWith(cValue));
или что-то в этом роде, подробнее здесь или здесь
Ответ №1:
В initState
, я делаю это —
_future1 = func.then(checkCode);
А затем я написал другую функцию для определения моего виджета в зависимости от кода, который я получаю —
checkCode(int statusCode) {
if (statusCode == 200) {
_future2Func();
widgetToNavigate = Text('');
} else {
widgetToNavigate = SomeWidget();
}}
Итак, наконец, мой код сборки выглядит так —
Widget build(BuildContext context) {
return FutureBuilder(
future: _future1,
builder: (BuildContext context, AsyncSnapshot snapshot) {
return snapshot.connectionState != ConnectionState.done
? CircularProgressIndicator()
: widgetToNavigate;
},
);}
Комментарии:
1. вы все еще используете два
FutureBuilder
s … — один incheckCode()
и другой inbuild()
метод2. Только если я получу 200 в первом. Мне нужно загрузить информацию и показать индикатор выполнения, пока информация не будет загружена… Это неправильно?
3. используйте один
FutureBuilder
внутреннийbuild()
метод, который либо создаетCircularProgressIndicator
, либоYourFinalWidget
когда вашFuture
завершается4. здесь вы можете прочитать, как бороться с ошибками с
FutureBuilder
помощью — я имею в виду:if (snapshot.hasError) { ...