javascript面试必备知识(4)单线程和异步

js面试必备知识,关注作者查看系列js知识体系

导语:JavaScript是一门单线程的语言,那么他要是在某一步卡死了,或者是请求资源等待响应,那是不是整个项目都停止了?答案是不是的,因为他有异步操作。

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

猜你喜欢

转载自blog.csdn.net/gitchatxiaomi/article/details/108035374
今日推荐