JS基础知识2.0(三)异步

Event-loop Promise Async/Await等

题目:
1.什么是单线程,和异步有什么关系
2.什么是event-loop
3.是否用过jQuery的Deferred
4.Promise的基本使用和原理
5.介绍一下async/await (和Promise的区别,联系)
6.总结一下当前JS解决异步的方案

知识点:
1.什么是单线程 和异步的关系

单线程 只有一个线程,只能做一件事
原因 避免DOM渲染的冲突
解决方案-异步


原因:避免DOM渲染冲突
浏览器需要渲染DOM
JS可以修改DOM结构
JS执行的时候,浏览器DOM渲染会暂停
两端JS也不能同时执行(都修改DOM就冲突了)
webworker支持多线程,但是不能访问DOM

        console.log('100')
        setTimeout(function()  {
            console.log('200')
        }, 1000)
        console.log('300')
        console.log('400') 


等待也属于一种占线程的形式

setTimeout 属于异步

        console.log('100')
        $.ajax({
            url: 'a.json',
            success: function(result){
                console.log(result)
            }
        })
        console.log('300')
        console.log('400')


$ajax加载完再执行

先让其他代码执行,最后再执行异步


解决方案:异步
问题一:没按照书写方式执行,可读性差
问题二:callback中不容易模块化


2.什么是event-loop
文字解释:
实例分析:
实战代码:

知识串联:
单线程 - 同时间只能做一件事
原因 - 避免DOM渲染冲突
解决方案 - 异步
实现方式 - event loop

事件轮询,是JS实现异步的具体解决方案
同步代码,直接执行
异步函数先放在异步队列中,
待同步函数执行完毕,轮询执行异步队列的函数

实例分析:


Chrome v8 ->c++

轮询执行:
一个就执行完就完了
两个异步函数时候,执行完了以后要继续监视异步队列,看看还有没有放入主线程,再回去监视,放主线程。


Dcba/dcab

回顾:
事件轮询,JS实现异步的具体解决方案
同步代码,直接执行
异步函数先放在异步队列中
setTimeout,0s,1s,AJax
待同步函数执行完毕,轮询执行 异步队列的函数


3.是否用过jQuery的Deferred

jQuery 1.5的变化->使用jQuery Deffered->初步引入prmoise的概念

链式操作
jQuert 1.5 的变化

变化:
无法改变JS异步和单线程的本质
只能从写法上杜绝callback这种形式
它是一种语法糖形式,但是解耦了代码
很多的体现:开放封闭原则

不用改之前的代码,可以各干各的,可以只测试扩展的代码。。等等

扩展开放修改封闭

回归测试,多人开发的好处,耦合减少


使用jquery deffered

        var wait = function () {
            var task = function () {
                console.log('执行完成')
                
            }
            setTimeout(task, 2000)
        }
        wait()
        function waitHandle() {
            var dtd = $.Deferred() //dtd是deffered的一个实例

            var wait = function (dtd) {
                var task = function () {
                    console.log('执行完成')

                    //成功
                    //dtd.resolve()

                    //失败
                    dtd.reject()
                }
                setTimeout(task, 2000)
                // wait 返回
                return dtd
            }
            //最终返回
            return wait(dtd)

        }
        var w = waitHandle()
        w.then(function () {
            console.log('ok 1')
        }, function () {
            console.log('error 1')
        }).then(function () {
            console.log('ok 2')
        }, function () {
            console.log('err 2')
        })

        // 开放封闭原则 可以分好多then来写 不用修改之前的


总结,dtd的API可以分成两类,用意不同
第一类 dtd.resolve dtd.reject
第二类 dtd.then dtd.done dtd.fail
.then 监听函数 被动受监听
Resolve,reject是发送消息
.then是接受消息。这两类应该分开,否则后果很严重


当有dtd.promise的时候,只能用dtd.then,dtd.done, dtd.fail,
已经把dtd.resolve,dtd.reject过滤掉了

        function waitHandle() {
            var dtd = $.Deferred() //dtd是deffered的一个实例

            var wait = function (dtd) {
                var task = function () {
                    console.log('执行完成')

                    //成功
                    //dtd.resolve()

                    //失败
                    dtd.reject()
                }
                setTimeout(task, 2000)
                // wait 返回
                return dtd.promise()
            }
            //最终返回
            return wait(dtd)

        }

        var w = waitHandle() //promise对象
        $.when(w).then(function () {
            console.log('ok 1')
        }, function () {
            console.log('error 1')
        })

4.Promise的基本使用和原理

基本语法回顾

        function loadImg(src) {
            var promise = new Promise (function (resolve, reject) {
                var img = document.createElement('img')
                img.onload = function () {
                    resolve(img)
                }
                img.onerror = function () {
                    reject()
                }
                img.src = src
            })
            return promise
        }

        var src = 'http://portrait8.sinaimg.cn/1401664575/blog/180'
        var result = loadImg(src)
        result.then(function (img) {
            console.log(1, img.width)
            return img
        }, function () {
            console.log('error 1')
        }).then(function (img) {
            console.log(2, img.height)
        }, function () {
            console.log('error 2')
        })


异常捕获  -》then只接受一个参数后面最后统一由一个catch进行捕捉

        var src = 'http://portrait8.sinaimg.cn/1401664575/blog/180'
        var result = loadImg(src)
        result.then(function (img) {
            console.log(1, img.width)
            return img 
        }).then(function (img) {
            console.log(1, img.height)
        }).catch(function (ex) {
            console.log(ex)
        })


多个串联


        var src = 'http://portrait8.sinaimg.cn/1401664575/blog/180'
        var result = loadImg(src)
        result.then(function (img) {
            console.log(1, img.width)
            return img 
        }).then(function (img) {
            console.log(2, img.height)
        }).catch(function (ex) {
            console.log(ex)
        })


Promise.all和Promise.race

        Promise.all([result1, result2]).then(function (datas) {
            console.log('all', datas[0])
            console.log('all', datas[1])
        })

        Promise.race([result1, result2]).then(function (data) {
            console.log('race', data)
        })


Promise标准

关于标准的闲谈
    任何技术标准使用都需要一套标准来支撑
    如 html js css http等, 无规矩不成方圆
    任何不符合标准的东西,终将会将被用户抛弃
   不要挑战标准,不要自造标准
状态变化
三种状态, pending,fulfilled ,rejected
初始状态是 pending
pending变为fulfilled ,或者 pending 变为rejected
状态变化不可逆
Then
Promise实例必须实现then这个方法
Then()必须接受两个函数作为参数
Then()返回的必须是一个Promise实例



5.介绍一下async/wait es7中的

then只是将callback拆分了

Async/await是最直接的同步写法

          function loadImg(src) {
            var promise = new Promise (function (resolve, reject) {
                var img = document.createElement('img')
                img.onload = function () {
                    resolve(img)
                }
                img.onerror = function () {
                    reject('图片加载失败')
                }
                img.src = src
            })
            return promise
        }

        var src1 = 'http://portrait8.sinaimg.cn/1401664575/blog/180'
        var src2 = 'https://www.bootcdn.cn/assets/img/bootstrap.svg?1545296853983'
        
        const load = async function () {
            const result1 = await loadImg(src1)
            console.log(result1)
            const result2 = await loadImg(src2)
            console.log(result2)
        }
        load()


语法

使用await,函数必须用async标识
await后面跟的是一个Promise实例
需要用babel-polyfill

问题解答:
什么是单线程,和异步有什么关系
什么是event-loop
是否用过jquery的Deferred
Promise的基本使用和原理
介绍一下async/await
总结一下当前JS解决异步的方案

1.单线程就是同时只能做一件事,两端JS不能同时执行
原因就是为了避免DOM渲染的冲突
异步是一种无奈的解决方案,虽然有很多问题
2.事件轮询,JS异步的解决方案
什么是异步队列,何时被放入异步队列
轮询的过程
3.可以用JQUERY 1.5对AJAX的改变举例
说明如何简单的封装,使用Deferred
说明Promise和Deffered区别
4.基本语法
如何异常捕获
多个串联-链式执行的好处
Promise.all,Promise.race
Promise标准,状态变化,then 函数、
5.基本语法async/await
使用了Promise,并没有和Promise冲突
完全是同步的写法,再也没有回调函数
但是:改变不了JS单线程,异步的本质
6.
Jquery Deffered
Promise
Async/Await
Generator//es6 
 

猜你喜欢

转载自blog.csdn.net/qq_37021554/article/details/86676491