Dart语言简介

变量声明

var

类似于 JavaScript 中的 var,它可以定义变量

最大的不同是 Dart 中 var 变量一旦赋值,类型便会确定,不能改变其类型

dynamic 和 Object

Object 是 Dart 所有对象的根基类,也就是说所有类型都是 Object 的子类(包含 Function 和 NULL),所以任何类型的数据都可以赋值给 Object 声明的对象,dynamic 与 var 一样都是关键词,声明的变量可以赋值任意对象。

相同之处

dynamic 与 Object 声明的变量可以在后期改变赋值类型

不同之处

dynamic 声明的对象编译器会提供所有可能的组合,而 Object 声明的对象只能使用 Object 的属性和方法,否则编译器会报错

final 和 const

如果你从未打算更改一个变量,那么使用 final 或 const,不是 var,也不是一个类型。一个 final 变量只能被设置一次。被 final 或者 const 修饰的变量,变量类型可以省略

不同之处

const 变量是一个编译时常量,final 变量在第一次使用时被初始化

函数

Dart 是一种真正的面向对象的语言,所以即使是函数也是对象,并且有一个类型 Function。这意味着函数可以赋值给变量或作为参数传递给其他函数,这是函数式编程的典型特征

函数声明

Dart 函数声明如果没有显式声明返回值类型时会默认当做 dynamic 处理,注意,函数返回值没有类型推断

可选的位置参数

包装一组函数参数,用[]标记为可选的位置参数

可选的命名参数

定义函数时,使用{param1, param2,...},用于指定命名参数

调用函数时,可以传参。如果传参,就必须使用指定形参的名称。例如:paramName: value

异步支持

Dart 类库有非常多的返回 Future 或者 Stream 对象的函数。这些函数被称为 异步函数 :它们只会在设置好一些耗时操作之后返回,比如像IO操作。而不是等到这个操作完成

async 和 await 关键词支持了异步编程,允许我们写出和同步代码很像的异步代码

Future

Future 与 JavaScript 中的 Promise 非常相似,表示一个异步操作的最终完成(或失败)及其结果值的表示。简单来说,它就是用于处理异步操作的,异步处理成功了就执行成功的操作,异步操作失败了就捕获错误或者停止后续操作。一个 Future 只会对应一个结果,要么成功,要么失败

Future 的所有 API 的返回值仍然是一个 Future 对象,所以可以很方便的进行链式调用

Future.then

    Future.delayed(new Duration(seconds: 2), (){
        return "hi.world";
    }).then((data){
        print(data);
    })

Future.catchError

如果异步任务发生错误,我们可以在 catchError 中捕获错误

    Future.delayed(new Duration(seconds: 2), (){
        return "hi.world";
    }).then((data){
        print(data);
    }).catchError((e){
        // 执行失败会走到这里
        print(e);
    })

不是只有 catchError 回调才能捕获错误,then 方法还有一个可选参数 onError,我们也可以用它来捕获异常

    Future.delayed(new Duration(seconds: 2), (){
        return "hi.world";
    }).then((data){
        print(data);
    }, onError: (e){
        print(e);
    });

Future.whenComplete

有些时候,我们会遇到无论异步任务执行成功或失败都需要做一些事的场景,比如在网络请求前弹出加载对话框,在请求结束后关闭对话框。

这种场景,有两种方法,第一种是分别在 then 或 catch 中关闭一下对话框,第二种就是使用 Future 的 whenComplete 回调

    Future.delayed(new Duration(seconds: 2), (){
        return "hi.world";
    }).then((data){
        // 执行成功会走到这里
        print(data);
    }, onError: (e){
        // 执行失败会走到这里
        print(e);
    }).whenComplete((){
        // 无论成功或失败都会走到这里
    });

Future.wait

它接收一个 Future 数组参数,只有数组中所有 Future 都执行成功后,才会触发 then 的成功回调,只要有一个 Future 执行失败,就会触发错误回调。

    Future.wait([
        // 2秒后返回结果
        Future.delayed(new Duration(seconds: 2), (){
            return 'hello';
        }),
        // 4秒后返回结果
        Future.delayed(new Duration(seconds:4), (){
            return ' world';
        })
    ]).then((results){
        print(result[0]+result[1]);
    }).catchError((e){
        print(e);
    })

Async/await

回调地狱(Callback Hell)

如果代码中有大量的异步逻辑,并且出现大量异步任务依赖其它异步任务的结果时,必然会出现 Future.then 回调中套回调情况

可以感受一下,如果业务逻辑中由大量异步依赖的情况,将会出现在回调里面套回调的情况,过多的嵌套会导致代码可读性下降以及出错率提高,并且非常难维护,这个问题被形象的称为回调地狱(Callback Hell)

使用 async/await 消除 callback hell

    Future<String> login(String userName, String pwd){
        // 用户登录
    }
    Future<String> getUserInfo(String id){
        // 获取用户信息
    }
    Future saveUserInfo(String userInfo){
        // 保存用户信息
    }

    task() async{
        try{
            String id = await login('alice', '*****');
            String userInfo = await getUserInfo(id);
            await saveUserInfo(userInfo);
        }catch(e){
            // 错误处理
            print(e);
        }
    }
  • async 用来表示函数是异步的,定义的函数会返回一个 Future 对象,可以使用 then 方法添加回调函数

  • await 后面是一个 Future,表示等待该异步任务完成,异步完成后才会往下走;await 必须出现在 async 函数内部

  • 其实,无论是在 JavaScript 还是 Dart 中,async/await 都只是一个语法糖,编译器或解释器最终都会将其转化为一个 Promise(Future) 的调用链

Stream

Stream 也是用于接收异步事件数据,和 Future 不同的是,它可以接收多个异步操作的结果(成功或失败)。也就是说,在执行异步任务时,可以通过多次触发成功或失败事件来传递结果数据或错误异常。Stream 常用于会多次读取数据的异步任务场景,如网络内容下载、文件读写等

    Stream.fromFutures([
        // 1秒后返回结果
        Future.delayed(new Duration(seconds: 1), (){
            return 'hello 1';
        }),
        // 抛出一个异常
        Future.delayed(new Duration(seconds: 2), (){
            throw AssertionError('Error');
        }),
        // 3秒后返回结果
        Future.delayed(new Duration(seconds: 3), (){
            return 'hello 3';
        })
    ]).listen((data){
        print(data);
    }, onError: (e){
        print(e.message);
    }, onDone: (){

    });

上面的代码依次会输出

    I/flutter (17666): hello 1
    I/flutter (17666): Error
    I/flutter (17666): hello 3
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 标签(空格分隔): Dart Flutter Dart在静态语法方面和Java非常相似,如类型定义、函数声明、泛型...
    黄昭鸿阅读 545评论 0赞 0
  • Dart的设计目标应该是既对标Java,也对标JavaScript,Dart在静态语法方面和Java非常相似,如类...
    寒桥阅读 7,200评论 3赞 11
  • 前言 最近要做flutter项目,Dart语法自然是前提,于是就在Dart学习和理解的过程中做了一些适合自己的知识...
    小哥_xiaoge阅读 559评论 0赞 1
  • Dart是什么? Dart是一门新的编程语言,如同JAVA、PHP一样,是为了解决编写应用程序中的一些实际问题而...
    浩之然阅读 835评论 0赞 1
  • 此文章是v1.0+时编写,年代久远,小心有毒,谨慎食用!!! 一些重要概念 所有的东西都是对象,所有的对象都是类的...
    soojade阅读 10,281评论 2赞 27

友情链接更多精彩内容