javascript异步编程的六种方式总结


Posted in Javascript onMay 17, 2019

异步编程

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

  1. 回调函数
  2. 事件监听
  3. 发布订阅模式
  4. Promise
  5. Generator (ES6)
  6. async (ES7)

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

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

function f1() {
  setTimeout(function(){
    console.log('先执行 f1')
  },1000)
}
function f2() {
  console.log('再执行 f2')
}

回调函数

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

回调函数的demo:

function f1(f2){
  setTimeout(function(){
    console.log('先执行 f1')
  },1000)
  f2()
}
function f2() {
  console.log('再执行 f2')
}

效果如下:

 javascript异步编程的六种方式总结

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

事件监听

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

事件监听的demo

$(document).ready(function(){
   console.log('DOM 已经 ready')
});

发布订阅模式

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

发布订阅模式的 demo

//订阅done事件
$('#app').on('done',function(data){
  console.log(data)
})
//发布事件
$('#app').trigger('done,'haha')

Promise

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

Promise 封装异步请求demo

export default function getMethods (url){
  return new Promise(function(resolve, reject){
    axios.get(url).then(res => {
      resolve(res)
    }).catch(err =>{
      reject(err)
    })
  })
}

getMethods('/api/xxx').then(res => {
  console.log(res)
}, err => {
  console.log(err)
})

Generator

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

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

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

Generator 的 demo

function *generatorDemo() {
 yield 'hello';
 yield 1 + 2;
 return 'ok';
}

var demo = generatorDemo()

demo.next()  // { value: 'hello', done: false } 
demo.next()  // { value: 3, done: false } 
demo.next()  // { value: 'ok', done: ture } 
demo.next()  // { value: undefined, done: ture }

async

async函数返回的是一个 Promise 对象,可以使用 then 方法添加回调函数,async 函数内部 return 语句返回的值,会成为 then 方法回调函数的参数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

1.await命令后面返回的是 Promise 对象,运行结果可能是rejected,所以最好把await命令放在try...catch代码块中。

async 的 demo1

async function demo() {
 try {
  await new Promise(function (resolve, reject) {
   // something
  });
 } catch (err) {
  console.log(err);
 }
}

demo().then(data => {
  console.log(data) // 
})

参考文献

https://developers.google.com/web/fundamentals/primers/promises
http://es6.ruanyifeng.com

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
学习jquery必备 api中英文对照的chm手册 下载
May 03 Javascript
JavaScript 克隆数组最简单的方法
Feb 12 Javascript
JavaScript中document对象使用详解
Jan 06 Javascript
封装属于自己的JS组件
Jan 27 Javascript
JS实现的样式切换功能tableCSS实例
Dec 30 Javascript
JavaScript如何一次性展示几万条数据
Mar 30 Javascript
Vue表单验证插件Vue Validator使用方法详解
Apr 07 Javascript
JS小球抛物线轨迹运动的两种实现方法详解
Dec 20 Javascript
微信小程序滑动选择器的实现代码
Aug 10 Javascript
微信小程序实现文字跑马灯
May 26 Javascript
浅谈layer弹出层按钮颜色修改方法
Sep 11 Javascript
适用于 Vue 的播放器组件Vue-Video-Player操作
Nov 16 Javascript
150行代码带你实现微信小程序中的数据侦听
May 17 #Javascript
angular4应用中输入的最小值和最大值的方法
May 17 #Javascript
jQuery实现的点击显示隐藏下拉菜单功能完整示例
May 17 #jQuery
详解 微信小程序开发框架(MINA)
May 17 #Javascript
Vue模板语法中数据绑定的实例代码
May 17 #Javascript
jQuery控制input只能输入数字和两位小数的方法
May 16 #jQuery
微信小程序云开发详细教程
May 16 #Javascript
You might like
解析PHP正则提取或替换img标记属性
2013/06/26 PHP
php读取3389的脚本
2014/05/06 PHP
使用PHP实现阻止用户上传成人照片或者裸照
2014/12/25 PHP
ThinkPHP中Common/common.php文件常用函数功能分析
2016/05/20 PHP
简单谈谈PHP中的Reload操作
2016/12/12 PHP
laravel-admin 实现在指定的相册下添加照片
2019/10/21 PHP
javascript 写类方式之五
2009/07/05 Javascript
用jquery与css打造个性化的单选框和复选框
2010/10/20 Javascript
JavaScript函数参数使用带参数名的方式赋值传入的方法
2015/03/19 Javascript
javascript实现无法关闭的弹框
2016/11/27 Javascript
javascript动画系列之模拟滚动条
2016/12/13 Javascript
AngularJS指令与指令之间的交互功能示例
2016/12/14 Javascript
详解Vue学习笔记进阶篇之列表过渡及其他
2017/07/17 Javascript
JavaScript闭包的简单应用
2017/09/01 Javascript
vue-ajax小封装实例
2017/09/18 Javascript
vue父组件向子组件传递多个数据的实例
2018/03/01 Javascript
JavaScript数据结构与算法之检索算法示例【二分查找法、计算重复次数】
2019/02/22 Javascript
Vue+ElementUI table实现表格分页
2019/12/14 Javascript
JavaScript设计模式--桥梁模式引入操作实例分析
2020/05/23 Javascript
Python中内建函数的简单用法说明
2016/05/05 Python
Python实现上下班抢个顺风单脚本
2018/02/07 Python
pyhton列表转换为数组的实例
2018/04/04 Python
Python创建一个空的dataframe,并循环赋值的方法
2018/11/08 Python
python创建与遍历List二维列表的方法
2019/08/16 Python
Python 网络编程之UDP发送接收数据功能示例【基于socket套接字】
2019/10/11 Python
导致python中import错误的原因是什么
2020/07/01 Python
浅谈Python爬虫原理与数据抓取
2020/07/21 Python
钳工实习自我鉴定
2013/09/19 职场文书
计算机网络专业个人的自我评价
2013/10/17 职场文书
2015年护士医德医风自我评价
2015/03/03 职场文书
2015年会计年终工作总结
2015/05/26 职场文书
2016感恩母亲节校园广播稿
2015/12/17 职场文书
2016年学校“3.12”植树节活动总结
2016/03/16 职场文书
使用canvas对video视频某一刻截图功能
2021/09/25 HTML / CSS
电脑无法安装Windows 11怎么办?无法安装Win11的解决方法
2021/11/21 数码科技
Mysql多层子查询示例代码(收藏夹案例)
2022/03/31 MySQL