Nodejs如何使单线程的Javascript实现异步编程
熟悉Javascript的同学一定听过一句话“Javascript是单线程的”,但神奇的是基于Javascript的Nodejs却十分适合在高并发场景下使用,Nodejs究竟是如何做的,本文带大家一起看下:
一、同步编程 VS 异步编程
1.什么是同步编程
看下官网的解释
从官网的描述当中,我们能大致将同步编程 与 代码顺序执行 划等号。
2.什么是异步编程
异步,即不同步,也就是说代码可以不按照顺序执行。
为什么不希望代码顺序执行?
是因为当主程序中出现一些网络请求、文件I/O操作时,如果按照代码顺序执行,那么后续所有的代码将无法执行,只有干等着这些耗时操作完成。
太不科学了,我反对。
因此,为了解决这个问题,异步编程就出现了。
二、异步编程的实现
1.回调函数
什么是回调函数:
官方的解释还是比较抽象,不妨用一个小栗子来去理解:
这里的A函数就是一个回调函数callback。callback原意为call then back(调用后返回),就是在主函数B中调用callback函数,callback函数执行完成后又立刻回到主函数,继续执行主函数中的代码。
问题:为什么不能在B函数中直接调用A函数?
因为通常在编写程序时,B函数都是语言内部或者其他开发者定义好的(如内置模块的方法),我们看不到也不能直接在B函数内部插入我们的代码。
那我们如何介入B函数的执行呢,此时就可以通过回调函数以参数的方式传递给B函数,B函数在内部再调用这个回调函数,并将结果返回(最关键)。
回调函数在异步编程中的应用
还是先看一个栗子
在B函数中有一个异步逻辑setTimeout,2秒后返回一个对象。
思考一下,我们如何拿到这个对象?
答案是可以借助回调函数,在回调函数A中我们可以通过result参数的方式,拿到异步逻辑执行后的返回值。
(其实,其实回调函数A最主要的功能也就在于此,帮助我们在B函数外部拿到B函数内部异步操作的执行结果)
2.回调函数在异步编程中的应用
在分析回调函数在异步编程中的应用之前,我们还是先看一个小栗子:
问:如何使用Nodejs读取三个文件x,y,z,文件的读取顺序是x -> y -> z
哈哈,这太简单了,上代码:
一顿操作,结果却发现
哈哈,小意思,再执行一次让你们看下
傻眼了,怎么会这样呢?我的顺序呢?
小结:fs.readFile是一个异步方法,也就是说实际上代码执行的顺序与代码编写的顺序不完全一致,那该怎么办?
换一种思路,既然回调函数可以是一个参数,并且能在回调函数中拿到主函数的执行结果,那能不能在回调函数中执行下一步操作,试一试。
看起来很好,运行下看看
再试一下
完结撒花!
3.思考
虽然上面实现了异步编程,但是这样一个场景出现时:
产品经理:突然有一个需求,有300个文件需要按照顺序读取,麻烦用回调函数实现。
我:好的,等等,多少,300层?
心理活动:我难道要嵌套300层,虽然可以实现,也太low了吧。可恶,得想想其他办法。
那如何优化,下一期我们将对异步调用的优化方案进行深入探讨。
转载自:https://juejin.cn/post/7208429397359902779