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 相关文章推荐
JavaScript.The.Good.Parts阅读笔记(二)作用域&闭包&减缓全局空间污染
Nov 16 Javascript
解决jquery异步按一定的时间间隔刷新问题
Dec 10 Javascript
用js判断输入是否为中文的函数
Mar 10 Javascript
jQuery层动画定位滑动效果的方法
Apr 30 Javascript
javascript制作的滑动图片菜单
May 15 Javascript
JavaScript中三种常见的排序方法
Feb 24 Javascript
JavaScript html5 canvas实现图片上画超链接
Oct 20 Javascript
Vue 按键修饰符处理事件的方法
May 04 Javascript
js实现每日签到功能
Nov 29 Javascript
Vuex 单状态库与多模块状态库详解
Dec 11 Javascript
微信小程序下拉加载和上拉刷新两种实现方法详解
Sep 05 Javascript
vue 点击其他区域关闭自定义div操作
Jul 17 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 按位与或 (^ 、&)
2013/06/21 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十三)
2014/06/26 PHP
PHP版微信小店接口开发实例
2016/11/12 PHP
Laravel5框架自定义错误页面配置操作示例
2019/04/17 PHP
juqery 学习之三 选择器 层级 基本
2010/11/25 Javascript
Javascript 类、命名空间、代码组织代码
2011/07/31 Javascript
SeaJS入门教程系列之SeaJS介绍(一)
2014/03/03 Javascript
js 获取input点选按钮的值的方法
2014/04/14 Javascript
jQuery中scrollLeft()方法用法实例
2015/01/16 Javascript
jQuery使用append在html元素后同时添加多项内容的方法
2015/03/26 Javascript
JavaScript动态修改弹出窗口大小的方法
2015/04/06 Javascript
文件上传,iframe跨域数据提交的实现
2016/11/18 Javascript
js验证手机号、密码、短信验证码代码工具类
2020/06/24 Javascript
js实现字符全排列算法的简单方法
2017/05/01 Javascript
php简单数据库操作类的封装
2017/06/08 Javascript
一个有意思的鼠标点击文字特效jquery代码
2017/09/23 jQuery
javascript数据类型中的一些小知识点(推荐)
2019/04/18 Javascript
JQuery特殊效果和链式调用操作示例
2019/05/13 jQuery
ES6 新增的创建数组的方法(小结)
2019/08/01 Javascript
layui自己添加图片按钮并点击跳转页面的例子
2019/09/14 Javascript
[36:43]NB vs Optic 2018国际邀请赛小组赛BO1 B组加赛 8.19
2018/08/21 DOTA
python的re模块应用实例
2014/09/26 Python
零基础写python爬虫之urllib2中的两个重要概念:Openers和Handlers
2014/11/05 Python
python实现矩阵打印
2019/03/02 Python
python3使用matplotlib绘制散点图
2019/03/19 Python
树莓派与PC端在局域网内运用python实现即时通讯
2019/06/22 Python
python 字典访问的三种方法小结
2019/12/05 Python
Python tempfile模块生成临时文件和临时目录
2020/09/30 Python
html2 canvas生成清晰的图片实现打印功能
2019/09/23 HTML / CSS
美国最便宜的旅游网站:CheapTickets
2017/07/09 全球购物
电钳专业个人求职信
2014/01/04 职场文书
师德师风个人自我剖析材料
2014/09/27 职场文书
后进基层党组织整改方案
2014/10/25 职场文书
道德模范事迹材料
2014/12/20 职场文书
赢在中国观后感
2015/06/02 职场文书
企业内部管理控制:银行存款控制制度范本
2020/01/10 职场文书