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