js面试必备知识,关注作者查看系列js知识体系
导语:JavaScript是一门单线程的语言,那么他要是在某一步卡死了,或者是请求资源等待响应,那是不是整个项目都停止了?答案是不是的,因为他有异步操作。
本文的目录
-
- 1,什么是同步和异步
- 2,异步和它造成的问题
- 三,对js单线程的知识点进行了补充,满满干货。
1,什么是同步和异步
我们先来看一段代码,你觉得他会输出什么?
console.log(100)
setTimeout(() => {
console.log(200)
}, 1000)
setTimeout(() => {
console.log(300)
}, 0)
console.log(400)
// 答案 100 400 300 200
我们先明确一个定义,JavaScript是一个单线程的语言,就是它只能同时做一件事,js和dom渲染共用一个线程,这就会导致在做一些需要响应的操作时,就会停住无法继续执行后面的代码。那为什么不给他变成多线程的呢?这是因为要是变成多线程,要是一个线程给dom文档添加东西,一个给删东西,那到底要以哪个为标准呢?所以导致JavaScript是一门单线程的语言。那怎么解决这些问题呢,就需要用到异步操作。
这里的setTimeout就是一个设置计时器的东西,然后设置一个回调函数,就是异步操作,JavaScript的异步不会阻塞后面代码的执行,等到时间到了就会执行这个异步操作。
2,异步和它造成的问题
相信大家都会遇到一个问题,去请求一个后台接口,然后在把请求到的东西加载到页面上,但是还没请求到资源,就已经把那些后续的操作执行完了,导致页面异常,很多的undefined。异步就能够把这个问题解决,通过回调函数将数据加载到页面上。
$.get(url, (res) => {
this.data = res.data
})
但是又会出现另外一个问题,要是你要将请求到的数据中的某个数据再去请求,以此往复,就会形成一个回调地狱(callback hell)。
$.get(url1, (res1) => {
this.data = res1.data
$.get(url2, (res2) => {
this.data = res2.data
$.get(url3, (res3) => {
this.data = res3.data
})
})
})
这种嵌套的方式几个还好,要是出现十多个,迟早会把程序员给绕晕,同时代码也不易维护。那么这个异步回调函数造成的回调地狱怎么解决呢?就要用到promise来解决。他能把这个嵌套的模式改写成一个链式的模式,从而比较容易写和看懂,方便维护。
function getData(url) {
return new Promise(
(resolve, reject) => {
$.ajax({
url,
success(data) {
resolve(data)
},
error(err) {
reject(err)
}
})
}
)
}
getData(url1).then(res => {
console.log(res.url2)
return getData(res.url2)
}).then(res => {
console.log(res.url3)
return getData(res.url3)
}).then(res => {
console.log(res)
}).catch(err => {
console.error(err)
})
这样就完美解决了这个嵌套的问题了,变成一条链式的形状。
三,对js单线程的知识点进行了补充,满满干货。
篇幅有点长,所以把它放在了另外的一篇博客中,超级详细,看完就能完全理解js的单线程。
https://blog.csdn.net/gitchatxiaomi/article/details/108054585