专栏名称: JavaScript
面向JavaScript爱好人员提供:前端最新资讯、原创内容、JavaScript、HTML5、Ajax、jQuery、Node.js等一系列教程和经验分享。
目录
相关文章推荐
51好读  ›  专栏  ›  JavaScript

总结异步编程的六种方式

JavaScript  · 公众号  · Javascript  · 2019-05-16 18:00

正文

众所周知 JavaScript 是 单线程 工作,也就是只有一个脚本执行完成后才能执行下一个脚本,两个脚本不能同时执行,如果某个脚本耗时很长,后面的脚本都必须排队等着,会拖延整个程序的执行。那么如何让程序像人类一样可以多线程工作呢?以下为几种异步编程方式的总结,希望与君共勉。

  • 回调函数

  • 事件监听

  • 发布订阅模式

  • Promise

  • Generator (ES6)

  • async (ES7)


异步编程传统的解决方案:回调函数事件监听

初始示例:假设有两个函数, f1 和 f2,f1 是一个需要一定时间的函数。

  1. function f1() {

  2. setTimeout(function(){

  3. console.log('先执行 f1')

  4. },1000)

  5. }

  6. function f2() {

  7. console.log('再执行 f2')

  8. }

回调函数

因为 f1 是一个需要一定时间的函数,所以可以将 f2 写成 f1 的 回调函数,将同步操作变成异步操作,f1 不会阻塞程序的运行,f2 也无需空空等待,例如 JQuery 的 ajax。

回调函数的demo:

  1. function f1(f2){

  2. setTimeout(function(){

  3. console.log('先执行 f1')

  4. },1000)

  5. f2()

  6. }

  7. function f2() {

  8. console.log('再执行 f2')

  9. }

效果如下:

总结:回调函数易于实现、便于理解,但是多次回调会导致代码高度耦合

事件监听

脚本的执行不取决代码的顺序,而取决于某一个事件是否发生。

事件监听的demo

  1. $(document).ready(function(){

  2. console.log('DOM 已经 ready')

  3. });

发布订阅模式

发布/订阅模式是利用一个消息中心,发布者发布一个消息给消息中心,订阅者从消息中心订阅该消息,。类似于 vue 的父子组件之间的传值。

发布订阅模式的 demo

  1. //订阅done事件

  2. $('#app').on('done',function(data){

  3. console.log(data)

  4. })

  5. //发布事件

  6. $('#app').trigger('done,'haha')

Promise

Promise 实际就是一个对象, 从它可以获得异步操作的消息,Promise 对象有三种状态,pending(进行中)、fulfilled(已成功)和rejected(已失败)。Promise 的状态一旦改变之后,就不会在发生任何变化,将回调函数变成了链式调用。

Promise 封装异步请求demo

  1. export default function getMethods (url){

  2. return new Promise(function(resolve, reject){

  3. axios.get(url).then(res => {

  4. resolve(res)

  5. }).catch(err =>{

  6. reject(err)

  7. })

  8. })

  9. }


  10. getMethods('/api/xxx').then(res => {

  11. console.log(res)

  12. }, err => {

  13. console.log(err)

  14. })

Generator

Generator 函数是一个状态机,封装了多个内部状态。执行 Generator 函数会返回一个遍历器对象,使用该对象的 next() 方法,可以遍历 Generator 函数内部的每一个状态,直到 return 语句。

形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式, yield是暂停执行的标记。

next() 方法遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值。

Generator 的 demo

  1. function *generatorDemo() {

  2. yield 'hello';

  3. yield 1 + 2;

  4. return 'ok';

  5. }


  6. var demo = generatorDemo()


  7. demo





    请到「今天看啥」查看全文