异步
1.单线程和异步
js本身是单线程语言,只能同时做一件事
浏览器和nodejs已支持JS启动进程,如web Worker
JS和DOM渲染共享同一个线程,因为JS可以修改DOM结构
2.我们都知道js是单线程
单线程---->只有一个线程,同时只能做一件事,两段js不能同时执行
原因:避免DOM渲染冲突
我们知道js可以修改DOM结构, js执行的时候,浏览器DOM渲染会暂停
两段js也不能同时执行,不然渲染DOM有冲突
webworker支持多线程,但是不能访问DOM
引出问题:我们不能遇到setTimeout就等着吧
解决方案就是:异步
event-loop:事件轮询,是js实现异步的具体解决方案
同步代码,直接执行
异步函数放在异步队列中
待同步函数执行完毕,轮询执行异步队列中的函数
异步引出问题:执行方式顺序问题
callback不容易模块化,异步代码回调地狱链,代码逻辑堆砌
解决方案: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 = 'https://www.imooc.com/static/img/index/logo_new.png' var result = loadImg(src) result.then(function (img) { console.log(1, img.width) return img //这里要返回img,下一个then才能使用 }, function () { console.log('error 1') }).then(function (img) { console.log(2, img.height) }) var src = 'https://www.imooc.com/static/img/index/logo_new.png' 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) })
//顺序加载两个图片需求
var src1 = 'https://www.imooc.com/static/img/index/logo_new.png' var result1 = loadImg(src1) var src2 = 'https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg' var result2 = loadImg(src2) result1.then(function (img1) { console.log('第一个图片加载完成', img1.width) return result2 // 重要!!! }).then(function (img2) { console.log('第二个图片加载完成', img2.width) }).catch(function (ex) { console.log(ex) }) var src1 = 'https://www.imooc.com/static/img/index/logo_new.png' var result1 = loadImg(src1) var src2 = 'https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg' var result2 = loadImg(src2) 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) })
async/await ====> then只是把callback拆分了,async/await直接是同步的写法,没有任何回调