一直有个疑问,用 nodejs 时有什么优雅的办法能让代码在流程上回避掉回调吗?

2019-01-15 22:41:36 +08:00
 tomoya92

虽然现在 ES 标准里加上了 async await 来实现同步操作,还有 Promise,但业务复杂了,代码还是会被各种回调弄的执行流程出问题

举个例子

写 js 的时候用的最多的应该就是回调了,回调里可以传很多个参数,简单的操作,这样写很方便,但业务复杂了,就不方便了,回调地狱也就是这样来的

这时候你可能会说不是有 Promise 吗,但用这货我觉得也就是把代码变的好看些,拿结果还是要靠 then 方法回调拿

到这你可能还会说,不是还有 async await 吗,这货确实不用从 then 函数的回调里拿数据了,但用 nodejs 多了就会发现,很多函数的调用的写法还是会用到回调,而且这时候还会在回调函数的前面加上个 async,我也是无语了,这不是又回到起点了吗,如下

it ('waitBody', async function() {
	await driver.sleep(500).wait('body', 30000).html().then(function(code) {
    	isPageError(code).should.be.false;
    })
})

当然也有用起来舒服的地方,比如 mongoose 的查询

const results = await UserModel.find({});

综上,难道就没有一个优雅的方法能让代码一行一行的执行吗,前一个结果执行完了,拿到结果再参与下一行代码的执行?

有人会说了,你上面不是说了 async await 了吗,它不就是这样用的吗?那为啥还要在回调的方法上用 async await 呢?总觉得有点换汤不换药,折腾来折腾去,还是离不了回调,但回调又会涉及到代码结构和流程控制上的问题

还请原谅我这小白的问题,相信很多学习 nodejs 的朋友都有过这样的疑惑 😂

8346 次点击
所在节点    Node.js
80 条回复
tomoya92
2019-01-16 14:57:36 +08:00
@yoshiyuki #59 其实用 nodejs 还有一个好处,就是快,开发效率要比 java 不知道高多少 :joy
yoshiyuki
2019-01-16 15:23:38 +08:00
@tomoya92 PHP 开发更快
TomVista
2019-01-16 15:36:42 +08:00
```
function some (callback){
}

function callback(callback2){
}

function callback2(callback3){
}
...


```
Ritr
2019-01-16 16:44:50 +08:00
js 本身就是异步的呀,所以我打算学个其他语言
reus
2019-01-16 17:19:33 +08:00
@wly19960911 我用多线程从来就不用考虑这个帖子提出的问题
justin2018
2019-01-16 22:31:15 +08:00
长时间不写 我总是会忘记~ 不知道为啥~~~
tomoya92
2019-01-16 23:11:01 +08:00
@justin2018 我经常用,都分不清,更别说长时间不用了😂
libook
2019-01-16 23:42:52 +08:00
如果执意使用回调函数的思想来设计程序的话,用什么语言都会有这个问题。

JS 是可以完全不用回调函数来设计数据流的,你都用 async await 了,为什么还要用回调函数来传递数据?可以拿出几个例子来,一定有更好的代码的组织方案的。
libook
2019-01-16 23:49:01 +08:00
it ('waitBody', async function() {
const code = await driver.sleep(500).wait('body', 30000).html();
isPageError(code).should.be.false;
})

这块没必要再用 then 了,你都用 await 了,那就一定是等着这段代码执行完再执行下一句。
lhx2008
2019-01-17 00:02:14 +08:00
@tomoya92 说 python 快我还信了,普通 js 真的不行,npm 装个包都不知道要多久,一升级就各种瞎改,异步也不好写,异常链+正常链+多线程都难搞死了,维护别人代码都想砍人
sagaxu
2019-01-17 00:10:28 +08:00
@tomoya92 那是你不熟悉现代 Java
busfool
2019-01-17 06:47:36 +08:00
没有,js 异步无法优雅处理
tomoya92
2019-01-17 09:20:00 +08:00
@sagaxu #71 我使用 java 还停留在 8 的版本上
zy445566
2019-01-17 10:05:27 +08:00
把所有的回调都封装成 Promise,然后返回给上面 await 就好了
KuroNekoFan
2019-01-17 10:31:20 +08:00
关于 promiseFunc.then(some_stuff)的观感问题,你可以
Promise.resolve()
.then(stuff_1)
.then(stuff_2)
//...
salamanderMH
2019-01-17 10:47:10 +08:00
promisify
no1xsyzy
2019-01-17 11:31:52 +08:00
@oyjw443523 #58 协程不就是 async/await 吗
其实 NodeJS ( Python 的也是)的 async/await 就是把异步变成协程写法。
——
@lhx2008 #70 yarn,请
——
其实异步除了回调、Promise/Future、async/await (包括协程)还有一种就是信号式。
信号式其实多线程下也能很好用,调用链清晰,程序本身就是个系统设计图。
缺点就是状态不能自然保留和共享(必然手动维护 context ),并且对一本道的代码没特别大的影响。
exonuclease
2019-01-17 14:36:11 +08:00
我搞了个 node 的 c++扩展 可以强制把异步调用同步执行 不过代价是性能
hoyixi
2019-01-20 13:51:40 +08:00
就你给的代码,你不想写 then 回调,
直接:
code = await。。。。
if (判断 code )。。。

这不就是同步写法吗,await 的优势就是能让你这么写啊,你又不用
angsheng
2019-12-28 23:03:12 +08:00
我个人就很喜欢写回调套回调,当发现回调卡死了写不下去时候比如 fs.statu 与 fs.read 的配套操作的时候,问题出在了整个处理流程的设计,反过头重新设计就是了。
当然我理解“回调地狱”,,,但我对 Promise、async/await 就感到特别头疼,总是想不起来这个对象怎么用,真希望能尊重下像我这种习惯写回调而不习惯新语法的。
nodejs 就是 IO 类 API 是与主线程分开的另一个线程(其本身是不是队列结构实在是忘了),所以这里姑且认为至少有两个线程,代码顺序的主线程和 IO 类 API 所在那个线程。Promise 之类折腾来去无非是换了个写法而已(从程序员的层面来看)。

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

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

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

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

© 2021 V2EX