一直有个疑问,用 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 的朋友都有过这样的疑惑 😂

8158 次点击
所在节点    Node.js
80 条回复
oott123
2019-01-15 22:46:54 +08:00
没有,这就叫异步,你可以改用 Python。
sagaxu
2019-01-15 22:48:41 +08:00
promise 不能 await?
lekai63
2019-01-15 22:51:14 +08:00
async 都不能忍受的话 要不考虑学个正经的偏后端语言?
misaka19000
2019-01-15 22:51:15 +08:00
最好的办法就是不写 JS (滑鸡)
EPr2hh6LADQWqRVH
2019-01-15 22:52:25 +08:00
promisify
tcdw
2019-01-15 22:56:45 +08:00
> 很多函数的调用的写法还是会用到回调

https://nodejs.org/api/util.html#util_util_promisify_original
Hanggi
2019-01-15 22:57:40 +08:00
你这个写的感觉有问题。你再好好看看。
tomoya92
2019-01-15 23:07:07 +08:00
@tcdw #6 感谢大佬指点,原来 nodejs 内置已经实现了一个 promise,并且有一定的规则,谢谢
wly19960911
2019-01-15 23:07:43 +08:00
这个和 nodejs 有什么关系呢,那异步你怎么解决异步回调的问题? async 已经很接近同步的写法了。

不是 nodejs 想这么做,而是逻辑上只有这样的处理啊,不断的回调,我知道你什么时候运行什么方法嘛?我只能等你运行完成之后调用我才知道,你可以选择同步,但是问题是同步又阻塞线程你满意嘛。。

另外你用 await 就用错了,是我我会这么用,虽然我接触 await 是在 flutter 里面。

it ('waitBody', async function() {
var a = await driver.sleep(500);
var b =await a.wait('body', 30000);
await html();
(function(code) {
isPageError(code).should.be.false;
})();
})
tomoya92
2019-01-15 23:08:22 +08:00
@Hanggi #7 前端萌新,一直都是迷迷糊糊的用 nodejs,最近觉得非常有必要把这个弄清楚,所以才发帖求助的,还请见谅 :joy
tomoya92
2019-01-15 23:10:09 +08:00
@wly19960911 #9 感谢指点,上面那段代码不是我写出来的,是 uirecorder 录制完成后自动生成的测试用例里的代码,我也觉得在回调上还用 async await 总觉得别扭 :joy
wly19960911
2019-01-15 23:10:44 +08:00
async 和 await 是把一切耗时的操作打上一个 await,然后整体下来看起来就像同步,而不是像你那样 promise 和 async 混搭
Pastsong
2019-01-15 23:13:44 +08:00
js 语言特色就是单线程异步,你要先理解 async 解决了什么问题
tomoya92
2019-01-15 23:14:56 +08:00
@wly19960911 #12 await 不是等待的意思吗?加上这个关键字后,后面的代码要等待这行代码执行完才往下继续执行,不应该是这个意思吗?
wly19960911
2019-01-15 23:18:55 +08:00
@tomoya92 #14 是的,然后你就没必要去不断的 写个 promise.then()去处理回调了,把 promise.then()的东西丢到一个方法里面,一个个 await 调用,实际上会比 promise.then()好看,而且逻辑上清晰。async 没有解决什么根本上的问题,只是一种新的写法让异步回调看起来像同步,把箭头函数里面的东西丢到一个封装方法里面,最后到达一个更直观的代码.
Sparetire
2019-01-16 01:55:05 +08:00
没看懂都 await 了,为什么还要 then。。讲道理是不会出现一个 then 的
autoxbc
2019-01-16 04:42:41 +08:00
这个例子本身写的不好,看面条代码脑子绕圈是正常反应,要先坚实自己,就不会被带偏

可以看 Promise 迷你书
omnip
2019-01-16 04:51:51 +08:00
试试这样
const code = await driver.sleep(500).wait('body', 30000).html();
isPageError(code).should.be.false;
edward8628
2019-01-16 05:31:48 +08:00
async 和 await 是目前最优雅的了
tomoya92
2019-01-16 08:01:07 +08:00
@Sparetire 跟着网上的教程学呀,发现用上 await 就能同步了,就用上了

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

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

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

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

© 2021 V2EX