手记

帮你解决javascript中的异步烦恼

首先,我们先来梳理明确几个问题。

  1. JavaScript是单线程的吗?

    一般情况下是单线程的,但不管在浏览器端还是node都是可以实现多线程执行的。

  2. 那么单线程和多线程哪个更好呢?

    没有更好的,只有是否适用场景,我们知道线程并不是计算机上的一个硬件资源,而是操作系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,线程是靠CPU来运行和调度,所以当线程多时就需要系统分配大量CPU资源来运行和调度,也可以说充分利用CPU资源,加快程序执行速度。单线程执行时,每一个时刻有且只能执行一个函数(任务),那么如果我们执行一个非常耗时的操作,岂不是整个程序都会卡在哪里了?是的,事实就是如此。所以JavaScript中可以通过异步编程机制来处理耗时的任务的,最常见的如ajax请求数据。

  3. 异步和多线程

    异步和多线程可以处理耗时任务,总结起来,当需要执行I/O操作时,使用异步操作比使用线程+同步 I/O操作更合适。当需要使用大量CPU操作的时候,多线程的优势就体现出来了。

下面我们梳理一下JavaScript中实现异步编程的几种方式。

1.回调函数

如果有二个函数,其中一个执行很耗时,那就可以考虑吧另一个函数写成改函数的回调,就能保证执行顺序。比如:function getData(){ajax获取数据,耗时操作},function render(){渲染数据},那么就把render()作为getData()的回调,getData()就不会阻塞主程序运行,当结果返回时就立即通知回调函数执行。

2.事件机制

我们可以在js中不仅可以使用原生支持的事件,我们还可以自定义自定事件,和自己触发事件。当我们需要一个异步操作时,就可以注册一个事件,然后在适当的时候触发事件就可以了。

3.设计模式

我们使用发布-订阅者模式可以实现类似于事件监听的效果,详细内容可以参考JavaScript设计模式。

4.Promises对象

简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。如getData()返回一个Promise对象,那么我们就可以直接这样getData().then(render()),看似是回调函数的一个比较顺眼的写法。

5.Generator 函数,async函数。

了解ES6/ES7的同学对着两个应该非常熟悉,这也是JavaScript发展过程中对异步编程做出的更高级的实现和更优雅的编程体验,像同步一样写异步代码。详细内容可以参考ES6/ES7相关文档。

总结

对一门语言特性的深入理解,可以更好地帮助我们写出高效优雅的代码。平常工作中我们可以使用一些异步流程控制库如:async,then.js,bluebird,Q,co等,可以通过npm安装或直接下载,上手方便,简单易用,可以快速解决你遇到的异步流程问题。

0人推荐
随时随地看视频
慕课网APP