ES 中要用 await,上一层的函数都要是 async 的?

2019-01-02 14:25:02 +08:00
 cstome
async function A() {
    let someData = await B();
    
    return someData;
}

async function B() {
    let someData = await C();
    
    //Some logic code
    return someResult;
}

async function C() {
    return new Promise();
}

A();

上面实例的,只有 C 是异步的,B 在调用 C 同步执行的时候,B 必须是异步函数。而 A()在调用 B 时需要 B 通过 C 的返回经过 B 的某些计算,再返回给 A,因此调用 B 的时候也要是同步的。想要让 B 同步,A 就必须是异步函数。

这样的话岂不是想要用 await,上层所有函数都必须是异步函数?

7573 次点击
所在节点    JavaScript
48 条回复
autoxbc
2019-01-02 15:20:28 +08:00
@cstome #14

如果 c 不需要 d 的返回值(既不需要异步状态的真实返回值,也不需要同步状态的 promise ),c 就是分界点

async function d(){}

function c(){
d();
}

你的例子无法改写,分界点在更高的位置。上面说用 promise 改写的理解有误,用了 async 和 await 就不应在调用链里写任何 promise
cstome
2019-01-02 15:21:27 +08:00
@zbinlin #19 加入我在 A 里面也需要获取 B 的结果在进行处理呢?

还是不可避免的要把 A 变成异步函数。

又或者使用 Promise 的话,就只能把后面的逻辑都写在 then 里:

```js
function A() {
B().then(res => {
//some logic
return someResult;
})
}
```

这样看起来就是不太好。。。
janxin
2019-01-02 15:34:48 +08:00
@cstome 这就是显示切换的缺点,想兼容不想大改只有用这种方式
zbinlin
2019-01-02 15:48:08 +08:00
@cstome 使用 async 函数有什么影响吗(不好的地方)?
jin5354
2019-01-02 15:56:05 +08:00
@cstome C 是个异步函数,B 调用了 C 且依赖 C 的返回值,那 B 肯定也是异步函数啊,同理 A,async/await 关键字就是在表明本函数是异步函数,但是可用类同步的姿势写,不可能跟同步写的一模一样的,设计出来就不是完全无感知的,你原文写法没毛病
shintendo
2019-01-02 16:00:36 +08:00
A 是否要等待 B 的结果,和 B 是否要等待 C 的结果,是两个不相关的异步事件,你想把哪个写成同步,就对哪个用 async/await,不能指望写了其中一个,另一个也自动变成同步了呀。
otakustay
2019-01-02 16:37:13 +08:00
async 就是个标记,当你需要等一个异步函数的时候,无论它的调用方是不是 async,都注定是异步了(用 promise 的 then 也一样是异步)
abc635073826
2019-01-02 16:44:36 +08:00
@CloudnuY 只有你说到了重点🌚
cstome
2019-01-02 18:03:43 +08:00
@abc635073826 #28
@CloudnuY #10

JS 的逻辑还就真是买东西的 Promise 把东西买回来就行,你爱上哪逛上哪逛。
cstome
2019-01-02 18:05:10 +08:00
@zbinlin #24 就是这样的话几乎所有函数都是 async,或者 Promise,感觉都不太好。
lzvezr
2019-01-02 18:29:44 +08:00
你可以直接 return 一个 promise,在 then 里面 return 最终会被捕获
```评论不支持 markdown
function A() {
return B().then(res => {
//some logic
return someResult;
})
}
await A()
最终得到的是 someResult
shynome
2019-01-02 18:30:28 +08:00
别用 async 和 Promise 了, cb 一直写下去吧,性能又好

对的就是有传染性,就是要 async 的
ayase252
2019-01-02 18:39:45 +08:00
一个函数里有一个异步操作就是异步啊,没毛病啊。
sagaxu
2019-01-02 19:33:12 +08:00
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/async_function

async function expression used as an IIFE,你可以用 IIFE 斩断这种传染性。
sagaxu
2019-01-02 19:38:40 +08:00
function a() {
(async () => {
// 此处可以 await
})();
}

a 是一个没有 async 的函数,a 里面使用了 await
zbinlin
2019-01-02 19:47:33 +08:00
@cstome 没什么不好的,看多了就习惯了,真的。
kcats
2019-01-02 19:51:04 +08:00
tc39 有个新的提议: top level await, 参见 https://github.com/tc39/proposal-top-level-await , 目前是 stage 2, 最新版 v8 已经实现了这个 proposal, 所以你可以在 chrome 控制台直接写 await 1 回车测试.
kcats
2019-01-02 19:52:23 +08:00
@kcats 不过好像和楼主的问题无关...
des
2019-01-02 22:53:57 +08:00
虽然不是上层必须 async,但还是 async 舒服。
不传染的话,你就得自己等待返回结果,然后处理

顺便提一下一个有意思的东西,fibjs,就是为了解决这些的
TwoDays91
2019-01-03 08:11:00 +08:00
如果你逻辑依赖异步那你只能这么写,你还没试过每个 async 都要写 try catch。建议风格统一不要 promise 混着用。

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

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

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

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

© 2021 V2EX