溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Flutter和Dart取消Future的方法有哪些

發(fā)布時間:2022-04-07 10:44:32 來源:億速云 閱讀:172 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹“Flutter和Dart取消Future的方法有哪些”,在日常操作中,相信很多人在Flutter和Dart取消Future的方法有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Flutter和Dart取消Future的方法有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

    使用異步包(推薦)

    async包由 Dart 編程語言的作者開發(fā)和發(fā)布。它提供了dart:async風格的實用程序來增強異步計算??梢詭椭覀?nèi)∠鸉uture的是CancelableOperation類:

    var myCancelableFuture = CancelableOperation.fromFuture(
      Future<T> inner, 
      { FutureOr onCancel()? }
    )
    
    // call the cancel() method to cancel the future
    myCancelableFuture.cancel();

    為了更清楚,請參閱下面的實際示例。

    完整示例

    應用預覽

    Flutter和Dart取消Future的方法有哪些

    我們要構建的應用程序有一個浮動按鈕。按下此按鈕時,將開始異步操作(這需要 5 秒才能完成)。按鈕的背景從靛藍變?yōu)榧t色,其標簽從“開始”變?yōu)椤叭∠保F(xiàn)在您可以使用它來取消Future。

    • 如果您在Future完成前 5 秒內(nèi)點擊取消按鈕,屏幕將顯示“Future已被取消”。

    • 如果您什么都不做,則 5 秒后屏幕將顯示“Future completed”。

    一個演示價值超過一千字:

    代碼

    1.通過執(zhí)行以下操作安裝異步包:

    flutter pub add async

    然后運行:

    flutter pub get

    2.main.dart 中的完整源代碼(附解釋):

    // main.dart
    import 'package:flutter/material.dart';
    import 'package:async/async.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            // Remove the debug banner
            debugShowCheckedModeBanner: false,
            title: '大前端之旅',
            theme: ThemeData(
              primarySwatch: Colors.indigo,
            ),
            home: const HomePage());
      }
    }
    
    class HomePage extends StatefulWidget {
      const HomePage({Key? key}) : super(key: key);
    
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      // this future will return some text once it completes
      Future<String?> _myFuture() async {
        await Future.delayed(const Duration(seconds: 5));
        return 'Future completed';
      }
    
      // keep a reference to CancelableOperation
      CancelableOperation? _myCancelableFuture;
    
      // This is the result returned by the future
      String? _text;
    
      // Help you know whether the app is "loading" or not
      bool _isLoading = false;
    
      // This function is called when the "start" button is pressed
      void _getData() async {
        setState(() {
          _isLoading = true;
        });
    
        _myCancelableFuture = CancelableOperation.fromFuture(
          _myFuture(),
          onCancel: () => 'Future has been canceld',
        );
        final value = await _myCancelableFuture?.value;
    
        // update the UI
        setState(() {
          _text = value;
          _isLoading = false;
        });
      }
    
      // this function is called when the "cancel" button is tapped
      void _cancelFuture() async {
        final result = await _myCancelableFuture?.cancel();
        setState(() {
          _text = result;
          _isLoading = false;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('大前端之旅')),
          body: Center(
            child: _isLoading
                ? const CircularProgressIndicator()
                : Text(
                    _text ?? 'Press Start Button',
                    style: const TextStyle(fontSize: 28),
                  ),
          ),
          // This button is used to trigger _getDate() and _cancelFuture() functions
          // the function is called depends on the _isLoading variable
          floatingActionButton: ElevatedButton(
            onPressed: () => _isLoading ? _cancelFuture() : _getData(),
            child: Text(_isLoading ? 'Cancel' : 'Start'),
            style: ElevatedButton.styleFrom(
                padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 30),
                primary: _isLoading ? Colors.red : Colors.indigo),
          ),
        );
      }
    }

    使用 timeout() 方法

    這種方法既快速又簡單。但是,它不是很靈活。

    使用timeout()方法,您可以限制Future的時間(例如 3 秒)。如果 future 及時完成,它的值將被返回。另一方面,如果Future超過限制時間,將執(zhí)行onTimeout函數(shù):

    Future<T> timeout(
       Duration timeLimit,
      {FutureOr<T> onTimeout()?}
    )

    快速示例

    創(chuàng)建一個虛擬的Future:

    Future<String?> _myFuture() async {
        await Future.delayed(const Duration(seconds: 10));
        return 'Future completed';
    }

    設置超時 3 秒:

    _myFuture().timeout(
          const Duration(seconds: 3),
          onTimeout: () =>
              'The process took too much time to finish. Please try again later',
    );

    將Future轉換為流

    您可以使用 Future 類的asStream()方法來創(chuàng)建一個包含原始Future結果的流?,F(xiàn)在您可以取消對該流的訂閱。

    快速示例

    // don't forget to import this
    import 'dart:async';
    
    // Create a demo future
    Future<dynamic> _loadData() async {
        await Future.delayed(const Duration(seconds: 10));
        return 'Some Data';
    }
    
    // a reference to the stream subscription
    // so that we can call _sub.cancel() later
    StreamSubscription<dynamic>? _sub;
    
    // convert the future to a stream
    _sub = _loadData().asStream().listen((data) {
        // do something with "data"
        print(data);
     });
    
    // cancel the stream subscription
    _sub.cancel();

    請注意,這個快速示例僅簡要描述了事物的工作原理。您必須對其進行修改以使其可在現(xiàn)有項目中運行。

    到此,關于“Flutter和Dart取消Future的方法有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

    AI