V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
zxCoder
V2EX  ›  JavaScript

这两种写法是一样的吗?

  •  
  •   zxCoder · 2021-09-04 19:14:08 +08:00 · 2402 次点击
    这是一个创建于 954 天前的主题,其中的信息可能已经有所发展或是发生改变。
    async fun(){
        return await findOne();
    }
    async fun(){
        return findOne();
    }
    

    findOne 是一个 async 函数

    19 条回复    2021-09-06 12:36:55 +08:00
    codehz
        1
    codehz  
       2021-09-04 19:22:09 +08:00 via Android
    有一点小区别,就是如果标记为 async 的 findOne 抛出异常,那第二个调用栈中是否包含 fun
    codehz
        2
    codehz  
       2021-09-04 19:25:46 +08:00 via Android
    说错了,第二种写法会导致外部无法捕获 findOne 的异常(
    cmdOptionKana
        3
    cmdOptionKana  
       2021-09-04 19:28:41 +08:00
    返回值的类型不一样,async 函数的返回值是 Promise<T>, 而对其加 await 可以获得类型 T
    Biwood
        4
    Biwood  
       2021-09-04 19:59:16 +08:00
    如果你不需要在 fun 函数里面用 try catch 捕获 findOne 的报错,那么这两个 fun 函数对于外部来说是一样的,甚至你把两种写法的 async 和 await 都去掉,结果也是一样。

    参考文档最后的说明 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/async_function#%E4%BD%BF%E7%94%A8async%E5%87%BD%E6%95%B0%E9%87%8D%E5%86%99_promise_%E9%93%BE
    aleen42
        5
    aleen42  
       2021-09-04 21:17:52 +08:00
    一样的,Unexpected Identifier, 你少了个 function 定义
    aleen42
        6
    aleen42  
       2021-09-04 21:26:42 +08:00   ❤️ 1
    另外, 由于 try...catch statement 对于 Promise 的处理方式有差异, 我认为不应该关注且尝试去运用, 因为这样的行为随时会被 TC39 修整导致不兼容

    ```js
    try { await Promise.reject(1) } catch { console.log('caught') } // => "caught"
    try { Promise.reject(1) } catch { console.log('caught') } // => throw "Uncaught (in promise) 1"
    ```
    mxT52CRuqR6o5
        7
    mxT52CRuqR6o5  
       2021-09-05 00:19:10 +08:00 via Android
    你第二个不写 async 都行
    2i2Re2PLMaDnghL
        8
    2i2Re2PLMaDnghL  
       2021-09-05 00:23:10 +08:00
    调用栈不一致,其他都一样。第二种续延序列中没有 fun,直接 findOne |> (outer),所以 findOne 抛的异常会直接给到 (outer)
    或者,反正所有 async/await 异步实质都是 CSP,干脆写成 CSP,约定形式 callback(error, value) 其中 error === null || value === null
    ```
    //1
    fun = (cb) => {findOne((e, v)=>{e?cb(e, null):cb(null,v)})}
    //2
    func = cb => findOne(cb)
    ```
    显然第一种写法允许对 e 进行更完善的处理。比如 #6 那样的话就是写成
    e?(console.log("caught"),cb(null,null)):cb(null,v)

    @aleen42 你这跟那个 1+1 返回 500 的故事一样……
    2i2Re2PLMaDnghL
        9
    2i2Re2PLMaDnghL  
       2021-09-05 00:26:02 +08:00
    不过还有人提到第三种写法
    fun(){return findOne();}
    对应的异步 CSP 形式是
    fun = findOne
    IvanLi127
        10
    IvanLi127  
       2021-09-05 00:29:24 +08:00 via Android
    应该是一样的,没什么区别
    aleen42
        11
    aleen42  
       2021-09-05 00:51:10 +08:00 via Android
    @2i2Re2PLMaDnghL async / await 的提出就是為了解決 CSP 的無限嵌套問題,難道你又想掉入回調深淵?
    muzuiget
        12
    muzuiget  
       2021-09-05 00:52:45 +08:00
    肯定不一样,调用栈不同,返回结果不同,自己跑一下就知道了。

    console.log(await fun1());
    console.log(fun1());
    console.log(await fun2());
    console.log(fun2());
    aleen42
        13
    aleen42  
       2021-09-05 00:54:17 +08:00 via Android
    另外,糾正下應該是 CPS (Continuation-Passing Style)?
    2i2Re2PLMaDnghL
        14
    2i2Re2PLMaDnghL  
       2021-09-05 00:54:59 +08:00
    @aleen42 ……话说我写错了,应该是 CPS
    是这里还原后比较容易分辨出差异,要分析语法糖的实际效果需要知道糖展开后是什么样的。
    liuidetmks
        15
    liuidetmks  
       2021-09-05 07:14:21 +08:00 via iPhone
    稍微写两行测试下不就知道了?
    autoxbc
        16
    autoxbc  
       2021-09-05 16:30:27 +08:00
    下面这个帖子对你有用,其中的高赞解答(#16)说的比较清楚了
    /t/789253
    lin07hui
        17
    lin07hui  
       2021-09-05 19:09:23 +08:00
    一样。
    两种写法都不推荐。await func() 这是为等待 func 异步运行完后再运行下一行代码,如果没一行代码,直接返回 func() 就行,不用加 await,没有用到 await 也就没必要加 async
    Kasumi20
        18
    Kasumi20  
       2021-09-06 11:29:34 +08:00
    @codehz 怎么就无法捕获了?
    libook
        19
    libook  
       2021-09-06 12:36:55 +08:00   ❤️ 1
    如果不考虑 try/catch 的话,两种写法就是一样的,promise 有个特性可以确保 resolve 返回的不是个 promise,而是层层 resolve 之后的值,比如主题里的第二个不加 await 的写法在外部调用 await fun()之后不至于返回的是个 promise 。

    @autoxbc #16 想点进去看看高赞是什么,竟然是我写的……
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4163 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 04:13 · PVG 12:13 · LAX 21:13 · JFK 00:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.