James369
V2EX  ›  Flutter

异步中 await 和 then 的区别,哪个更好

  •  
  •   James369 · Apr 23, 2021 · 6505 views
    This topic created in 2022 days ago, the information mentioned may be changed or developed.
    await 虽然简洁。因为 await 需要等待返回才继续向下执行,如果是较耗时的操作就得等待。


    方式一:
    await u = login();
    getUserInfo(u);
    otherTask(); // 必须等待 login()返回。


    方式二:
    login().then((u) {
    getUserInfo(u);
    );
    otherTask(); //可以并行

    我觉得 then 更加符合逻辑。
    Supplement 1  ·  Apr 23, 2021
    同意楼下有位 V 友说的“要有更好的结构来使用 await”,对于 await 来说需根据具体场景谨慎使用。
    46 replies  •  2021-04-30 07:42:03 +08:00
    IGJacklove
    IGJacklove
    Apr 23, 2021 via Android
    1
    这有什么好比的。。。。那你要是十个异步你嵌套十个 then 吗?
    James369
    James369
    OP
    Apr 23, 2021
    2
    @IGJacklove 嵌套总比使用不当好吧
    renmu123
    renmu123
    Apr 23, 2021 via Android❤️1
    3
    u=login()
    othertask()
    await u
    getuserinfo ()

    js 是这样的
    dzdh
    dzdh
    Apr 23, 2021
    4
    如果你 then 里面要做多步且必须要每一步需要前一个返回值呢。嵌套吗
    treblex
    treblex
    Apr 23, 2021❤️2
    5
    如果下一步需要上一步的结果就用 await 转成同步,否则都直接 then

    ```dart
    var uid = await login().then((u) {
    return u.id
    );
    otherTask(uid);
    ```
    pabupa
    pabupa
    Apr 23, 2021 via Android
    6
    await 是为了避免回调地狱的语法糖,他的实现方式也是回调。
    至于非阻塞的调用,你需要使用 wait 方法(传入多个 future )。
    ymcz852
    ymcz852
    Apr 23, 2021
    7
    用 async/await 一样的,还美观点
    方式一:
    otherTask();
    await u = login();
    getUserInfo(u);
    free9fw
    free9fw
    Apr 23, 2021
    8
    await 解决 callback hell 的
    icanfork
    icanfork
    Apr 23, 2021 via iPhone
    9
    不知道从何说起,楼主还是继续用 promise 吧
    walpurgis
    walpurgis
    Apr 23, 2021 via Android❤️5
    10
    await 外面再套一层 async 就行了

    (async()=>{
    await u = login();
    getUserInfo(u);
    })();
    otherTask();
    hereIsChen
    hereIsChen
    Apr 23, 2021❤️1
    11
    这个看习惯,我都是混着用的,容易出问题的就用 then catch
    层数多的就用 await
    IGJacklove
    IGJacklove
    Apr 23, 2021 via Android
    12
    感觉你刚学编程没多久的样子。。。
    whileFalse
    whileFalse
    Apr 23, 2021
    13
    @walpurgis 你可真是个小机灵鬼
    yunyuyuan
    yunyuyuan
    Apr 23, 2021
    14
    哈哈,居然有这种问题。
    单手拿手机好还是双手拿手机好?
    learningman
    learningman
    Apr 23, 2021 via Android
    15
    await 其实不是等待,你可以理解为暂停的只有当前线程,CPU 在 await 的时间内干别的去了
    这种说法很不准确,推荐你了解协程相关的内容
    shakaraka
    shakaraka
    Apr 23, 2021
    16
    rxjs 得永生
    lneoi
    lneoi
    Apr 23, 2021
    17
    这不是哪个好的问题吧 如果这种不必等待的 本来就不能让他被卡住 使用 await 之前应该注意避免这种情况的
    cxe2v
    cxe2v
    Apr 23, 2021
    18
    otherTask 不需要等待前面的结果的话,你把它放在 await 前面不就行了?
    rogi
    rogi
    Apr 23, 2021
    19
    不喜欢 then 链,还是喜欢 async/await 这种写法,同步发送异步请求的方法楼上已经说了
    acmore
    acmore
    Apr 23, 2021
    20
    “因为 await 需要等待返回才继续向下执行” 说明你还在用同步思维来异步编程。
    可以试着想一下程序不是 “向下” 执行的,而是多个单元同时执行的,相较于早早地完成下一步,所有单元整体上尽早完成才是更重要的。

    如果你的程序设计是让主线程卡在 await 上了,那么要么用 then,缺点是失去了上下文的同步控制;要么就重新整理一下 code,一定有更好的结构来使用 await.
    phony2r
    phony2r
    Apr 23, 2021
    21
    我觉得你的理解有问题
    yaphets666
    yaphets666
    Apr 23, 2021
    22
    js 吗 当然 then 好 async 和 await 的异常处理是业界难题 没有统一且玩美的方案
    um1ng
    um1ng
    Apr 23, 2021
    23
    async/await yyds
    Niphor
    Niphor
    Apr 23, 2021
    24
    方式一:
    otherTask();
    await x = login().then(getUserInfo);

    方式二:
    login().then(getUserInfo);
    otherTask(); //可以并行

    😈
    des
    des
    Apr 23, 2021
    25
    // 不需要 then
    pLogin = login();
    otherTask();
    u = await pLogin;
    getUserInfo(u);
    lonelymarried
    lonelymarried
    Apr 23, 2021
    26
    必须 await 啊,看起来都舒服些
    huijiewei
    huijiewei
    Apr 23, 2021
    27
    @yaphets666

    ```
    export const flatry = <T, E>(promise: Promise<T>): Promise<{ data: T | undefined; error: E | undefined }> => {
    return promise.then((data) => ({ data, error: undefined })).catch((error) => ({ data: undefined, error }));
    };
    ```
    ALVC666
    ALVC666
    Apr 23, 2021
    28
    两个其实都是一样的东西
    看你预期结果吧
    await 我觉得主要是异常处理的写法问题
    try catch 我觉得也很不美观
    charlie21
    charlie21
    Apr 23, 2021 via iPhone
    29
    真是敢问敢答阿
    hoyixi
    hoyixi
    Apr 23, 2021❤️2
    30
    你吐槽的 await 槽点,正是 await 诞生的原因,哈哈
    好比勺子是用来喝汤之类,用在筷子不方便的场合,而你吐槽:勺子竟然不能像筷子一样夹菜。
    yaphets666
    yaphets666
    Apr 23, 2021
    31
    @huijiewei 没看太懂 意思 flatry 是一个函数 把 await xxxx 传进去转换成 promsie 返回?
    @ALVC666 try catch 有时候捕获不到 await 结果的错误
    component
    component
    Apr 23, 2021
    32
    Promise.all Promise.race Promise.allSettled 你们是真不知道还是配合他演戏呢?
    MyouiSouth
    MyouiSouth
    Apr 23, 2021
    33
    @component Promise 跑错片场了,这儿是 dart,应该是 Future.wait (狗头
    TomatoYuyuko
    TomatoYuyuko
    Apr 23, 2021
    34
    await 最麻烦的地方是 reject 要用 try catch 捕获,处理起来有点麻烦,别的位置倒是用起来很顺手
    TomatoYuyuko
    TomatoYuyuko
    Apr 23, 2021
    35
    最近在用 async/await 做接口封装遇到了 catch 的坑,最后用了一种不太好的办法处理
    // response 拦截
    // showStatus 是用来弹框提示状态码国际化标语的方法
    ...
    catch (err) {
    reject({ code: err.status, msg: showStatus(err.status), data: null })
    }

    //post 方法的拦截
    ...
    catch (err) {
    return new Promise(resolve => {
    resolve({
    code: -1,
    msg: '',
    data: null
    })
    })
    }
    // 具体接口封装
    ...
    if(res.code !== -1){
    ...
    强行 resolve,这样就避开了在 api 部分写太多 try catch 的问题
    应该有更好的解决方法。。
    ALVC666
    ALVC666
    Apr 23, 2021
    36
    @TomatoYuyuko
    我是参考了这个
    https://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript/

    import to from './to.js';

    async function asyncTask() {
    let err, user, savedTask;

    [err, user] = await to(UserModel.findById(1));
    if(!user) throw new CustomerError('No user found');

    [err, savedTask] = await to(TaskModel({userId: user.id, name: 'Demo Task'}));
    if(err) throw new CustomError('Error occurred while saving task');

    if(user.notificationsEnabled) {
    const [err] = await to(NotificationService.sendNotification(user.id, 'Task Created'));
    if (err) console.error('Just log the error and continue flow');
    }
    }
    TomatoYuyuko
    TomatoYuyuko
    Apr 23, 2021
    37
    @ALVC666 懂了,确实是个方法,相当于封了一层 promise 处理 err...
    gledos
    gledos
    Apr 23, 2021
    38
    test
    chengxy
    chengxy
    Apr 23, 2021
    39
    @component #32 他们估计都不知道 Promise.all...
    leelz
    leelz
    Apr 23, 2021
    40
    js 走错片场了。。
    tonyaiken
    tonyaiken
    Apr 24, 2021 via iPhone
    41
    @IGJacklove 我们公司就是这样写的,嵌套很多层异步。
    IGJacklove
    IGJacklove
    Apr 24, 2021 via Android
    42
    @tonyaiken 这代码能看。。。。不可能不用 await 只嵌套吧。
    tonyaiken
    tonyaiken
    Apr 24, 2021 via iPhone
    43
    @IGJacklove 能看,可以分离出单独的方法。就变成方法嵌套方法。
    tonyaiken
    tonyaiken
    Apr 24, 2021 via iPhone
    44
    @IGJacklove 这是我们公司开源的内部使用的异步框架 https://github.com/linkedin/parseq
    xiubin
    xiubin
    Apr 24, 2021
    45
    笑死了。。一个苦逼 iOS er 一直等带能使用 await 。。。居然举这么个例子。。
    williamx
    williamx
    Apr 30, 2021 via Android❤️1
    46
    使用的场景不同,很多时候就是要等上一条执行完了才执行下一条,有时候不需要等待只需要执行完的通知,那么就用 then,否则就是 await,有时侯不想每个都加 async 或者有些函数不能加,那只能用 then 。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2493 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 83ms · UTC 15:12 · PVG 23:12 · LAX 07:12 · JFK 10:12
    ♥ Do have faith in what you're doing.