1. 异步和同步
JavaScript是单线程语言,所谓"单线程",就是指一次只能完成一件任务。遇到等待(网络请求、定时任务)会卡住,所以需要异步模式。
同步和异步的区别:
同步模式:后一个任务等待前一个任务结束,然后再执行,如果遇到等待会阻塞代码的执行;
异步模式: 后一个任务不等待前一个任务结束就可以执行,不会阻塞代码的执行。异步通过callback形式调用。
具体来说,异步运行机制如下:
(1)所有同步任务都在主线程上排队依次执行,形成一个执行栈。
(2)主线程之外,还存在一个"任务队列"(task queue)。异步任务进入Event Table并注册函数,异步任务有了运行结果,就在“任务队列”之中放置一个事件。
(3)一旦主线程中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入主线程执行。
(4)主线程内的任务执行完毕为空,就会从"任务队列"中读取事件,这个过程是循环不断的,形成event loop(事件循环)
//异步 通过callback形式调用 异步不会阻塞代码执行
console.log(100)
setTimeout(() => {
alert(200)
},1000)
console.log(400) //100,400 ,200
//同步 必须点击确认,400才能打印出来,同步会阻塞代码执行
console.log(100)
alert(200)
console.log(400)
异步方案经历了如下的四个进化阶段:
回调函数 —> Promise —> Generator —> async/await。
2.回调函数时期
异步的实现方式:事件监听,发布订阅,回调函数
异步可以同时进行多个操作,不会阻塞代码的执行,但同时他也有缺点,它使代码变得很复杂,比如一个页面进行多个ajax请求时:
$.get(url1,(data1) => {
console.log(data1)
//获取第二份数据
$.get(url2, (data2) => {
console.log(data2)
//获取第三份数据
$.get(url3, (data3) => {
console.log(data3)
//还可以继续获取数据
})
})
})
这样的代码会变得难以调试,并且极易出错,这就是callback hell(回调地狱)。
ES6的新语法Promise对象解决了callback hell问题。
3. Promise
Promise 对象用于表示一个异步操作的最终结果(完成或失败),以及其返回的值。
const https = require('https');
function httpPromise(url){
return new Promise(function(resolve,reject){
https.get(url, (res) => {
resolve(data);
}).on("error", (err) => {
reject(error);
});
})
}
httpPromise()
.then(function(data){
console.log(data)
})
.catch(function(error){
console.log(error)
})
//在上面这个例子里,当我们用 resolve 切换到了成功态后,Promise 的逻辑就会走到 then 中的传入的方法里去;
// 用 reject 切换到失败态后,Promise 的逻辑就会走到 catch 传入的方法中去。
httpPromise(url1)
.then(res => {
console.log(res);
return httpPromise(url2);
})
.then(res => {
console.log(res);
return httpPromise(url3);
})
.then(res => console.log(res));。
4. Generator
5. Async await
async/await的出现是将异步函数变成同步写法,使复杂的代码更可读。
async关键字声明一个函数为异步函数:
async function httpRequest() {
}
await关键字将异步方法变成同步方法,阻塞了代码的执行,它是等待异步方法执行完成,然后获取异步方法里的数据,但是必须用在异步方法里。
async function httpRequest() {
let res1 = await httpPromise(url1)
console.log(res1)
}
//我们给 httpPromise(url1) 这个异步任务应用了 await 关键字后,整个函数会暂停下来,直到异步任务的结果返回后,它才会被“唤醒”,继续执行后面的语句。