有个傻子,第一次用某雷下载大片,就是大人看的片,咳咳咳。。。 某雷告诉他,下载时间要俩小时,傻子心想,要俩小时呐,我第一次用某雷,我得盯着它下载,啥也不能干 因而傻子就干瞪着电脑,等着片下完,这俩小时,傻子啥也没干 后来,傻子变聪明了,他想,反正某雷在帮他下载,这俩小时,他彻底能够干干其余事情啊,好比学学计算机知识呀等等 等某雷下完了,再回来看呗 因而傻子潜心研究计算机知识,直到有一天他看到了有关于异步的知识,忽然间明白了
原来他等待某雷下完,啥也不干的过程就叫作同步
后来他在某雷下载过程当中自学计算机知识的过程就叫作异步
面试
同步
英文:Synchronization
wiki解释:指在一个系统中所发生的事件(event),之间进行协调,在时间上出现一致性与统一化的现象。
是否是很难理解?其实就是代码要等待到结果,才能继续进行【你能够理解为同步阻塞了代码继续执行】
segmentfault
异步
英文:Asynchronization
【在同步前面加了个A】
wiki解释就不贴了,有兴趣的朋友能够本身搜索看一下,反正我看的也挺头疼其实就是代码不用等待到结果,就能继续进行【你能够理解为异步不阻塞代码继续执行】
啥意思咧,让咱们看个你们都见过的例子promise
function wait() { setTimeout(() => console.log(this), 3000) } wait() // 三秒钟后,获得结果 console.log(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) })
// 假设有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
异步
解决方案一【当即执行函数建立独立做用域】async
// 假设有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 } }
请见回调是个什么鬼?this
请见浅析Promisecode
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后执行
await
改变了整个代码的执行顺序.它可让你用同步写代码的方式去写异步代码
若是你在一个函数内使用了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() }
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') }