• 【面试题】JS基础-异步


    1. 异步

    1.1 为什么要异步?

    JS是单线程语言,只能同时做一件事。JS和DOM渲染共用同一个线程,因为JS可修改DOM结构。当遇到等待的情况时,例如网络请求、定时任务,程序不能卡住。所以需要异步来解决JS单线程等待的问题,异步通过回调callback函数的形式实现。

    1.2 异步和同步

    同步和异步的区别:异步不会阻塞代码执行,同步会阻塞代码执行。

    • 异步
    // 异步(callback回调函数)
    console.log(100)
    setTimeout(()=>{
        console.log(200)
    }, 1000)
    console.log(300)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    • 同步
    console.log(100)
    alert(200)
    console.log(300)
    
    • 1
    • 2
    • 3

    不点击弹框的 确认 按钮,就不会执行console.log(300)

    2. 异步的应用场景

    • 网络请求,如ajax图片加载
    // ajax
    console.log('start')
    $.get('./data1.json', function(data1){
    	console.log(data1)
    })
    console.log('end')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    // 图片加载
    console.log('start')
    let img = document.createElement('img')
    img.onload = function(){
    	console.log('loaded')
    }
    img.src = '/xxx.png'
    console.log('end')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 定时任务,如setTimeout
    // setTimeout
    console.log(100)
    setTimeout(function(){
    	console.log(200)
    }, 1000)
    console.log(300)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    // setInterval
    console.log(100)
    setInterval(function(){
    	console.log(200)
    }, 1000)
    console.log(300)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3. promise的基本使用

    3.1 promise可以解决callback hell的问题

    在这里插入图片描述

    function getData(url){
        return new Promise((resolve, reject) => {
            $.ajax({
                url,
                success(data){
                    resolve(data)
                },
                error(err){
                    reject(err)
                }
            })
        })
    }
    
    const url1 = '/data1.json'
    const url2 = '/data2.json'
    const url3 = '/data3.json'
    
    // Promise的基本用法,管道串联的形式
    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))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    3.2 手写Promise加载图片

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>手写Promise加载图片title>
    head>
    
    <body>
        <script>
            function loadImg(src) {
                const p = new Promise(
                    (resolve, reject) => {
                        const img = document.createElement('img')
                        img.onload = () => {
                            resolve(img)
                        }
                        img.onerror = () => {
                            reject(new Error(`图片加载失败 ${src}`))
                        }
                        img.src = src
                    }
                )
                return p;
            }
    
            const url1 = 'https://profile-avatar.csdnimg.cn/fb030a9b9de24f4ba6dd8cd6c094ffcf_zx1041561837.jpg!1'
            const url2 = 'https://img-home.csdnimg.cn/images/20201124032511.png'
    
            loadImg(url1).then(img1 => {
                console.log('图片1的宽度为:' + img1.width)
                return img1    // 普通对象
            }).then(img1 => {
                console.log('图片1的高度为:' + img1.height)
                return loadImg(url2)    // promise对象
            }).then(img2 =>{
                console.log('图片2的宽度为:' + img2.width)
                return img2
            }).then(img2 => {
                console.log('图片2的高度为:' + img2.height)
            }).catch(ex => console.error(ex))
        script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    在这里插入图片描述

    4. JS异步相关面试题

    console.log(1)
    setTimeout(function(){
        console.log(2)
    }, 1000)
    console.log(3)
    setTimeout(function(){
        console.log(4)
    }, 0)
    console.log(5)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

  • 相关阅读:
    2023(2024届)计算机保研经验分享,圆梦山东大学
    Spring MVC中如何进行类型Converter呢?
    设计模式---原型模式
    SpringBoot SpringBoot 开发实用篇 4 数据层解决方案 4.18 查询文档
    Python飞机大战小游戏
    【Javascript】构造函数的参数写法
    SonarQube中的Quality Gate失败不会使Teamcity中的构建失败
    树莓派4B安装ROS的方法总结
    全志科技A40i国产开发板——性能参数综合测试
    Java之IO简述 第一篇——File类
  • 原文地址:https://blog.csdn.net/zx1041561837/article/details/128032504