这两种写法是一样的吗?

2021-09-04 19:14:08 +08:00
 zxCoder
async fun(){
    return await findOne();
}
async fun(){
    return findOne();
}

findOne 是一个 async 函数

2412 次点击
所在节点    JavaScript
19 条回复
codehz
2021-09-04 19:22:09 +08:00
有一点小区别,就是如果标记为 async 的 findOne 抛出异常,那第二个调用栈中是否包含 fun
codehz
2021-09-04 19:25:46 +08:00
说错了,第二种写法会导致外部无法捕获 findOne 的异常(
cmdOptionKana
2021-09-04 19:28:41 +08:00
返回值的类型不一样,async 函数的返回值是 Promise<T>, 而对其加 await 可以获得类型 T
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
2021-09-04 21:17:52 +08:00
一样的,Unexpected Identifier, 你少了个 function 定义
aleen42
2021-09-04 21:26:42 +08:00
另外, 由于 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
2021-09-05 00:19:10 +08:00
你第二个不写 async 都行
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
2021-09-05 00:26:02 +08:00
不过还有人提到第三种写法
fun(){return findOne();}
对应的异步 CSP 形式是
fun = findOne
IvanLi127
2021-09-05 00:29:24 +08:00
应该是一样的,没什么区别
aleen42
2021-09-05 00:51:10 +08:00
@2i2Re2PLMaDnghL async / await 的提出就是為了解決 CSP 的無限嵌套問題,難道你又想掉入回調深淵?
muzuiget
2021-09-05 00:52:45 +08:00
肯定不一样,调用栈不同,返回结果不同,自己跑一下就知道了。

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

@autoxbc #16 想点进去看看高赞是什么,竟然是我写的……

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/799885

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX