JavaScript异步编程与单线程机制解析

作者:拾光

时间:2026-10-24

浏览:182

本文深入解析JavaScript的单线程特性及异步处理机制,探讨网络请求与定时任务中的阻塞问题。通过对比回调函数与Promise,详解如何解决“回调地狱”,并介绍Promise.all和Promise.race在多接口并发场景下的具体应用与区别。

文章目录

单线程

然而在实际开发中,若涉及网络请求或定时任务,同步等待操作完成会导致页面卡顿。为此,JavaScript引入了异步机制以优化用户体验。

异步

异步执行不会阻塞后续代码的运行,而是等待同步任务结束后再处理异步任务,这与同步代码会阻断执行流程形成对比。异步机制主要应用于网络请求和定时任务等场景。

异步是通过callback的方式实现的,在callback里面执行异步执行的代码,但是有一些场景比如我们有三个网络请求abc需要依次执行,在a的回调里发起b请求,在b的回调里发起c请求,这样会造成一种很混乱的写法,称之为回调地狱,可以试想一下,如果页面逻辑过于复杂,需要依次调用10个接口,那么代码的可读性会非常非常差,我们如果看到了别人的这种代码难免内心奔跑一万只神兽。

Promise基本用法:


let fun1 = function(flag){
    return new Promise((resolve,reject)=>{
    if(flag){
        setTimeout(() => {
        resolve("success")
        }, 1000);
    }else{
        setTimeout(() => {
        reject("fail")
        }, 1000);
    }
    })
}
  
fun1(true).then((res)=>{
    console.log(res)//success
}).catch((res)=>{
    console.log(res)
})
fun1(false).then((res)=>{
    console.log(res)
}).catch((res)=>{
    console.log(res)//fail
})

上述代码展示了一个基础的Promise函数。该函数返回一个Promise对象,接收一个函数作为参数,该函数包含resolve和reject两个回调。当调用resolve()或reject()时,Promise状态发生变化。

若执行resolve(),则调用链中的then()方法将被触发,并接收resolve返回的参数;

若执行reject(),则调用链中的catch()方法将被触发,并接收reject返回的参数;

使用Promise重构上述三个网络请求的问题:


let callService = function(url){
      return new Promise((resolve,reject)=>{
          axios.get(url).then((res)=>{
            resolve(res)
          }).catch((err)=>{
            reject(err)
          })
      
      })
    }
    const url1 = "/user/url1"
    const url2 = "/user/url2"
    const url3 = "/user/url3"
    callService(url1).then((res)=>{
      // do something
      return callService(url2)
    }).then(()=>{
      // do something
      return callService(url3)
    }).then((res)=>{
      // do something
    }).catch((err)=>{
      console.log(err)
    })

采用上述方式重构后,代码结构扁平化,仅保持单层调用,从而避免了深层嵌套的回调地狱。

Promise.all

Promise.all用于将多个Promise实例包装为一个新的实例。当所有实例成功时,返回一个包含结果的数组;若任一实例失败,则立即返回失败的值。

Promise.all方法可有效处理日常开发中多接口并发调用的场景。


let p1 = new Promise((resolve, reject) => {
  resolve('成功了')
})

let p2 = new Promise((resolve, reject) => {
  resolve('success')
})

Promise.all([p1, p2]).then((result) => {
  console.log(result)               //['成功了', 'success']
}).catch((error) => {
  console.log(error)
})

Promise.race

该方法用于实现多个接口的“赛跑”,返回最先完成(成功或失败)的那个结果。


Promise.race([p1, p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error) 
})

以上是对JavaScript异步与单线程机制的详细解析,更多相关技术文章请持续关注本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章