一、同步和异步有何不同
单线程和异步
- js是单线程语言,只能同时做一件事
- 浏览器和node.js已支持JS启动进程,如Web Worker
- JS和DOM渲染共用同一个线程,因为JS可修饰DOM结构
- 遇到等待(网络请求,定时任务)时不能卡住,就需要异步
- 回调callback函数的形式
- 异步的必要性:基于JS是单线程语言
- 异步不会阻塞代码执行
- 同步会阻塞代码执行
JS如何执行
- 从前到后,一行一行执行
- 如果某一行执行报错,则停止下面代码的执行
- 先把同步代码执行完,再执行异步代码
同步
//同步
console.log(111);
alert(222)
console.log(333);
异步
//异步
console.log(100);
setTimeout(()=>{
console.log(200);
},2000);
console.log(300);
异步的应用场景
- 网络请求,如Ajax图片加载
- 定时任务,如setTimeout
promise的基本应用
promise的出现:callback hell的不合理性
callback hell:
//获取第一份数据
$.get(url1, (data1) => {
console.log(data1);
//获取第二份数据
$.get(url2, (data2) => {
console.log(data2);
//获取第三份数据
$.get(url3, (data3) => {
console.log(data3);
})
})
})
promise
function getData(url) {
return new Promise((resolve, reject) => {
$.ajax({
url,
success(data) {
resolve(data) //返回resolve执行then语句
},
error(err) {
reject(err) //返回reject执行catch语句
}
})
})
}
const url1 = '/data1.json'
const url2 = '/data2.json'
const url3 = '/data3.json'
getData(url1).then(data1 => {
console.log(data1);
return getData(url2)
}).then(data2 => {
console.log(data2);
return getData(url3)
}).then(data3 => {
console.log(data3);
}).catch(err => console.error(err))
promise把回调函数写成管道式串联的形式,不是callback hell的嵌套形式,有利于调试和阅读
面试题
手写promise加载一张图片
function loadImg(src) {
const p = new Promise((resolve, reject) => {
const img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
const err = new Error(`图片加载失败 ${src}`)
reject(err)
}
img.src = src
})
return p
}
const url = 'https://www.imooc.com/static/img/index/logo2020.png'
loadImg(url).then(img =>{
console.log(img.width);
return img
}).then(img => {
console.log(img.height);
}).catch(ex => { console.Error(ex) })
setTimeout笔试题
console.log(1);
setTimeout(() => {
console.log(2);
},1000)
console.log(3);
setTimeout(() => {
console.log(4);
},0)
console.log(5);
//打印顺序 1 3 5 4 2