1.同步和异步
1.1先说个傻子的故事
有个傻子,第一次用某雷下载大片,就是大人看的片,咳咳咳。。。
某雷通知他,下载时刻要俩小时,傻子心想,要俩小时呐,我第一次用某雷,我得盯着它下载,啥也不醒目
因而傻子就干瞪着电脑,等着片下完,这俩小时,傻子啥也没干
厥后,傻子变聪清楚明了,他想,横竖某雷在帮他下载,这俩小时,他完全能够乾乾其他事变啊,比方学学计算机学问呀等等
等某雷下完了,再回来看呗
因而傻子潜心研究计算机学问,直到有一天他看到了有关于异步的学问,突然间邃晓了
本来他守候某雷下完,啥也不干的历程就叫做同步
厥后他在某雷下载历程当中自学计算机学问的历程就叫做异步
1.2 同步与异步的观点
同步
英文:Synchronization
wiki诠释:指在一个体系中所发作的事宜(event),之间举行谐和,在时刻上涌现一致性与统一化的征象。
是否是很难明白?实在就是代码要守候到效果,才继承举行【你能够明白为同步壅塞了代码继承实行】
异步
英文:Asynchronization
【在同步前面加了个A】
wiki诠释就不贴了,有兴致的朋侪能够本身搜刮看一下,横竖我看的也挺头疼实在就是代码不必守候到效果,就可以继承举行【你能够明白为异步不壅塞代码继承实行】
啥意思咧,让我们看个人人都见过的例子
function wait() {
setTimeout(() => console.log(this), 3000)
}
wait() // 三秒钟后,获得效果
console.log(1) // 假如没有异步的话,我得等三秒钟才实行,所以,谢谢异步
2.罕见的异步题目
2.1图片加载题目
// 前提条件:用户的浏览器第一次要求这个图片,也就是用户的浏览器未缓存
document.getElementsByTagNames('img')[0].width // 宽度为 0
为何width会为0呢?
由于js运转的时刻,img并没有下载终了
解决方案
let imgNode = document.getElementsByTagName('img')[0]
imgNode.addEventListener('onload',function () {
console.log(this.width)
})
2.2 面试题常考的异步题目
// 假设有5个li
let liList = document.querySelectorAll('li')
for (var i = 0; i < liList.length; i++) {
liList[i].onclick = function () {
console.log(i) // 5 5 5 5 5
}
}
为何呢?
由于onclick事宜是异步处置惩罚的,用户触发onclick事宜时,轮回早已完毕,此时的i是5
解决方案一【马上实行函数建立自力作用域】
// 假设有5个li
let liList = document.querySelectorAll('li')
for (var i = 0; i < liList.length; i++) {
!(function (j) {
liList[j].onclick = function () {
console.log(j) // 5 5 5 5 5
}
})(i)
}
解决方案二【运用let】
// 假设有5个li
let liList = document.querySelectorAll('li')
for (let i = 0; i < liList.length; i++) {
liList[i].onclick = function () {
console.log(i) // 5 5 5 5 5
}
}
3.拿到异步效果的体式格局 —— 回调
请见回调是个什么鬼?
4.Promise
5.async / await 语句
5.1 大略相识await
mdn诠释:await 操纵符用于守候一个Promise 对象。它只能在异步函数 async function 中运用
然则await终究做了什么事变呢?
let setPromise = function () {
return new Promise((resolve, reject) => {
// 你的异步代码
setTimeout(() => {
resolve('success')
}, 10000)
})
}
let result = await setPromise()
假如你这个时刻在控制台不停输入result。
控制台会不停地报错
控制台报错:result is not defined
直到10s后,才胜利
为啥报错呢?定名let result了呀
由于await在守候setPromise()完成后,才会实行let result =
也就是说await 让前面的 let 和 = 异步了
能够你会问:
如许一搞,result也异步了,那我岂不是还要回调?
那末再来看下一个题目
let setPromise = function () {
return new Promise((resolve, reject) => {
// 你的异步代码
setTimeout(() => {
resolve('success')
}, 10000)
})
}
let result = await setPromise()
console.log(1) // 叨教这句代码是在10秒后被实行,照样马上实行?
答案:10s后实行
5.2 所以await终究醒目嘛
await
改变了全部代码的实行递次.它能够让你用同步写代码的体式格局去写异步代码
5.3 那末async又是干啥的呢?
假如你在一个函数内运用了await,那末你最幸亏一个函数的前面加上async
let setPromise = function () {
return new Promise((resolve, reject) => {
// 你的异步代码
setTimeout(() => {
resolve('success')
}, 2000)
})
}
function test() {
return result = await setPromise()
}
console.log(3)
控制台直接会报错:Uncaught SyntaxError: await is only valid in async function
啥意思咧 —— await只允许在 async function 内运用
也就是说,要在函数声明的时刻就加上 async
async function test() {
let result = await setPromise()
}
5.4 Promise异步操纵失利的状况
let setPromise = function () {
return new Promise((resolve, reject) => {
// 你的异步代码
setTimeout(() => {
reject.call(undefined)
}, 2000)
})
}
let result = await setPromise()
console.log(result)
// 浏览器又报错了 Uncaught (in promise) undefined
由于没有then/catch来处置惩罚Promise异步操纵失利的效果
所以我们此次运用try...catch...
语句
let setPromise = function () {
return new Promise((resolve, reject) => {
// 你的异步代码
setTimeout(() => {
reject.call(undefined)
}, 2000)
})
}
try {
let result = await setPromise()
console.log(result)
} catch(rejected) {
// 触发这一句
console.log('error')
}