写在前面

  JS因为是单线程的,所以在执行事务的时候,往往会因为某个事务的延迟,而导致服务器假死,这时候异步编程就显的格外重要,但是异步编程一般理解为回调函数callback,典型的就是node,回调函数的层层嵌套又导致程序过于冗余,因为闭包的存在,导致了内存的泄露或者误改上一层回调函数的参数,于是又有一个疑问,能不能用同步的方式去写异步,ES6的promise就是以同步流程的方式写出异步操做,但是piomise原生操作写起来比较长,能不能简介操作promise,ES7就又出现async/await的概念,与async/await同等语法糖作用的有依赖co库的generator函数,generator函数也是用来解决异步操作,不过得依赖co库,co 函数库是著名程序员 TJ Holowaychuk 于2013年6月发布的一个小工具,用于generator函数的自动执行。

  好了,那就罗列出js的异步操作

  1、回调函数

    ajax典型的异步操作,利用XMLHttpRequest,回调函数获取服务器的数据传给前台  

    之前也分析过ajax(飞机票)

    回调函数的含义就是耗时任务f1中执行f2,f1不会堵塞住,而是先执行f2,再延迟执行f1

  2、事件监听

    addEventListener

    当监听事件发生时,先执行回调函数,再对监听事件进行改写

  3、观察者模式,也叫订阅发布模式

    多个观察者可以订阅同一个主题,主题对象改变时,主题对象就会通知这个观察者

    其中步骤包括,订阅、发布、退订;先订阅(subscribe)一个主题对象,根据主题对象发布(publish)内容,期间也退订(unsubscribe)主题对象,一旦退订就无法再次发布

    可以把订阅一个主题对象理解成监听一个事件

    观察者模式的一个特点就是一旦主题事件一改变,就会通知整个观察者;观察者模式还可以计算出订阅事件的个数

  4、promise

    上面也提到了,promise是异步编程的解决方案,是一种容器,保存着异步操作的结果,可以把异步函数以同步函数的形式写出来

    promise第一个特点:对象状态不受外界影响,有三个状态pending(),fulfilled(),rejected(),只有异步操作才会更改这个状态,其他操作无法改变这个状态

    promise第二个特点:一旦状态改变,pending->fulfilled或pending->rejected,状态就会凝固住,称为resolve,通过promise的回调函数可以立即得到这个结果,与事件监听不同,一旦事件错误,就无法再次监听

    promise第三个特点:避免了回调函数的层层嵌套,实际上写promise时,虽然没有回到函数的层层嵌套,但是又有then的嵌套,这个又有新的解决方法

    promise第一个缺点:一旦promise建立,就会立即执行,无法中途停止

      举个例子,假如去淘宝买东西,去看上一个东西,想要买,已经点击确定购买了,但是你又cancle了,突然你发现工资发了,你又发送一个请求说又要买了,服务器接收到了你的第一个异步请求,你又有异步请求,异步请求又不能停止,求服务器阴影面积?

    promise的第二个缺点:promise不设置回调函数,抛出的错误无法在外部捕获

    piomise的第三个缺点:处于pending状态,无法知道进展到哪个状态

    下面一个经典的案例:用promise写出ajax,就体现了promise的特点

             function getJSON(url){
var promise = new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.open("get",url);
xhr.onreadystatechange=ajax;
xhr.responseType = "json";
xhr.setRequestHeader("Accept", "application/json");
xhr.send();
function ajax(response){
if (this.readyState !=4) {
return;
}
if (this.status ==200) {
resolve(this.response)
}else{
reject(new Error(this.status.responseText))
} }
})
return promise;
}
getJSON("/new2").then(function(value){
console.log(value);
},function(error){
console.log(error);
})
   5、es7语法糖async/await

     async异步函数是promise的完成状态,async函数直接then去获取状态改变值,catch来获取错误

     await只允许在async内部使用,就是async异步函数内部想要继续then,就可以采用await异步函数,await异步函数是内部的async异步函数

       async极大精简了promise的操作   

async  function asyncFn(){
return 123;
}
asyncFn()
.then(x => {console.log(x)})
.catch(err => console.log(error))

    这是未精简的promise操作,功能是把最终结果return最外层的promise,但是 用到了多层嵌套,比较复杂

    const fn = () => {
return getJSON()
.then(data =>{
if(data.params){
return otherGetJSON(data).then(otherdata =>{
console.log(otherdata);
return otherdata;
})
}else{
console.log(data)
}
})
}

    而async异步函数,直接去return出结果就行,这就是await是async内部async异步函数

    const fn = async () => {
const data = await getJSON();
if(data.params){
const otherdata = await otherGetJSON(data);
console.log(otherdata);
return otherdata;
}else{
console.log(data)
return data;
}
}
    6、co库的generator函数

      generator函数是一个异步函数,只有异步操作有结果才会交还执行权

      generator用到了ES6的遍历Iterator的概念,创建一个指针对象,指向数据结构的起始位置,每次next指向下一个指针结构成员,直至指向的下一个结构成员为undefined

      generator概念就是,每次遍历读用next方法,内部指针从结构头部指向下一个结构成员,直至下一个结构成员为undefined,遇到yield或return时会返回value和done参数,value表示yield或return的值,done表示是否结束 

function * gen(x){
var y = yield x +2;
return y;
}
var g = gen(1);
console.log(g.next()) // { value: 3, done: false }
console.log(g.next()) // { value: undefined, done: true }

      yield是遍历的停止标志

      而generator中的yield*表示 yield* 后面跟着一个可遍历的结构

 写在后面

    最近的review,让我对js又有新的认识,js异步操作是js的核心所在,也是js迷人的地方,async/await和generator都是promise的语法糖,我觉得没有优劣之分,可能道行太浅,还需刷道,希望业界前辈多多指责我,让我进步更快。

    好了,今天的交流就结束了,下次复习js定时器的内存分配等。

JS进阶 ] 分析JS中的异步操作的更多相关文章

  1. js进阶 12-13 jquery中one方法和trigger方法如何使用

    js进阶 12-13 jquery中one方法和trigger方法如何使用 一.总结 一句话总结: 1.one()方法和on()方法的区别是什么? 除了one()只执行一次,其它和on()一模一样,包 ...

  2. js进阶 11-18 jquery中操作选择器的方法有哪些

    js进阶 11-18 jquery中操作选择器的方法有哪些 一.总结 一句话总结:add().addBack().end() 1.add()方法是干嘛的,举一例? 将add()方法后选择器选择的jqu ...

  3. js进阶 11-3 jquery中css属性如何操作

    js进阶 11-3  jquery中css属性如何操作 一.总结 一句话总结:通过css()方法 1.attr和css是有交叉的,比如width,两者中都可以设置,那么他们的区别是什么? 其实通俗一点 ...

  4. js进阶 10-6 jquery中的属性选择器有哪些

    js进阶 10-6 jquery中的属性选择器有哪些 一.总结 一句话总结: 1.第一遍能学会么? 一遍是肯定学不会的,要多学几遍,所以想着怎么加快速度,减少学习的遍数 2.属性选择器是干嘛的? 选择 ...

  5. js进阶 10-5 jquery中的层级选择器有哪些

    js进阶 10-5 jquery中的层级选择器有哪些 一.总结 一句话总结: 1.jquery中的层级选择器有哪些? 四种,后代,子代,兄弟,相邻兄弟 2.如何区别jquery中的层级选择器? 记住这 ...

  6. js进阶 10-4 jquery中基础选择器有哪些

    js进阶 10-4 jquery中基础选择器有哪些 一.总结 一句话总结: 1.群组选择器用的符号是什么? 群组选择器,中间是逗号 2.jquery中基础选择器有哪些? 5种,类,id,tag,群组, ...

  7. js进阶 10-3 jquery中为什么用document.ready方法

    js进阶 10-3  jquery中为什么用document.ready方法 一.总结 一句话总结: 1.document.ready和window.onload的区别:用哪个好? document. ...

  8. js进阶 9-10 html中如何遍历下拉列表

    js进阶 9-10  html中单选框和多选框如何遍历下拉列表 一.总结 一句话总结: 1.select元素的options.length可以获取选择长度,然后用options[i]精确定位到选项,用 ...

  9. js 进阶 10 js选择器大全

    js 进阶 10 js选择器大全 一.总结 一句话总结:和css选择器很像 二.JQuery选择器 原生javaScript中,只能使用getELementById().getElementByNam ...

随机推荐

  1. 关于python下安装PIL库遇到的问题及解决办法

    关于python下安装PIL库遇到的问题及解决办法 关于python下安装PIL库遇到的问题及解决办法 :在下面这个网址下载pipllow(a replacement for PIL) www.lfd ...

  2. HTML DOM元素关系与操作

    <html> <head><title>DOM元素关系与操作</title></head> <body> <!-- div ...

  3. MySQL(四)--练习题

     2.1 编写一条 SQL 语句,从 Product(商品)表中选取出“登记日期(regist_date)在 2009 年 4 月 28 日之后”的商品.查询结果要包含 product_name 和 ...

  4. maven(二) maven项目构建ssh工程(父工程与子模块的拆分与聚合)

    前一节我们明白了maven是个什么玩意,这一节就来讲讲他的一个重要的应用场景,也就是通过maven将一个ssh项目分割为不同的几个部分独立开发,很重要,加油 --WH 一.maven父工程与子模块的拆 ...

  5. Day2_数字类型_字符串类型_列表类型_元组_字典_集合_字符编码_文件处理

    数字类型: 作用:年纪,等级,薪资,身份证号等: 10进制转为2进制,利用bin来执行. 10进制转为8进制,利用oct来执行. 10进制转为16进制,利用hex来执行. #整型age=10 prin ...

  6. Watson Explorer Analytical Components 3 - use case scenarios

    The followings are the user case scenarios that WEX can be used for generating value. 1.Customer Ins ...

  7. 总结两种动态代理jdk代理和cglib代理

    动态代理 上篇文章讲了什么是代理模式,为什么用代理模式,从静态代理过渡到动态代理. 这里再简单总结一下 什么是代理模式,给某个对象提供一个代理对象,并由代理对象控制对于原对象的访问,即客户不直接操控原 ...

  8. 基于vue2.0的一个豆瓣电影App

    1.搭建项目框架 使用vue-cli 没安装的需要先安装 npm intall -g vue-cli 使用vue-cli生成项目框架 vue init webpack-simple vue-movie ...

  9. acm->stl

    容器 queue 队列 定义 queue的定义需要两个参数,一个是元素类型,一个容器类型,元素类型是必要的,容器类型是可选的,默认为deque类型 基本方法 push(x) 入队,将x接到队列的末端 ...

  10. 如何在通过knockout数据绑定的DOM元素上添加事件

    通过knockout数据绑定的DOM元素,通过chrome控制台打断点知道,DOM元素会被暂时隐藏,使用document.querySelector()是获取不到的,会显示null,直到数据绑定完成才 ...