面试题 异步 和 单线程

异步和单线程

  • 题目
  • 知识点
  • 解答

题目

  • 同步和异步的区别是什么?
  • 手写用 promise 接在一张图片
  • 前端使用异步场景有哪些?
    在这里插入图片描述

知识点

  • 单线程和异步
  • 应用场景
  • callback hell 和 Peomise

单线程和异步

  • JS 是单线程语言,只能同时做一件事儿
  • 浏览器和 nodejs 以支持 JS 启动进程,如 Web Worker
  • JS 和 DOM 渲染共同一个线程,因为 JS 可修改 DOM 结构
  • 遇到等待(网路请求,定时任务)不能卡住
  • 需要异步
  • 毁掉 callback 函数形式

在这里插入图片描述

异步和同步

  • 基于 JS 是单线程语言
  • 异步不会阻塞代码执行
  • 同步会阻塞代码执行

应用场景

  • 网络请求,如 ajax 图片加载
  • 定时任务,如 setTimeout
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

问题解答

同步和异步的区别是什么?

基于 JS 是单线程语言
异步不会阻塞代码执行
同步会阻塞代码执行

同步是阻塞模式,异步是非阻塞模式。
同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,知道收到返回信息才继续执行下去;
异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回式系统会通知进程进行处理,这样可以提高执行的效率。

手写用 Promise 加载一张图片

Promise产生的原因
常见的回调地狱场景:


// 回调地狱  callback hell
// 获取第一份数据
$.get(url1, (data1) => {
    
    
    console.log(data1)
    //获取第二份数据
    $.get(url2, (data2) => {
    
    
        console.log(data2)
        //获取第三份数据
        $.get(url3, (data3) => {
    
    
            console.log(data3)
            //...
        })
    })
}

如上所示,多异步容易出现以下问题:

多异步返回的执行顺序不可控。
多异步的异常错误处理非常繁杂。
多异步嵌套,会导致回调地狱。

我们急需要一个能够保证异步执行顺序,保证执行和抛出错误的异步处理的保证范式来解决这些问题。ES6给我们的答案就是Promise。
用 promise处理同样的多异步问题:


function getData(url) {
    
    
            return new Promise((resolve, reject) => {
    
    
        $.ajax({
    
    
            url,
            success(data) {
    
    
                resolve(data)
            },
            error(err) {
    
    
                reject(data)
            }
        })
    })
}
var url1 = '/datà1.json'
var url2 = '/datà2.json'
var url3 = '/datà3.json'
getData(url1).then(data1 => {
    
    
    console.log(data1)
    return getData(url2)
}).then(data2 => {
    
    
    console.log(data1)
    return getData(url3)
}).then(data3 => {
    
    
    console.log(data3)
}).catch(err => {
    
    
    console.log(err)
})

promise把callback 形式变成了非嵌套的形式,变成了串联的形式

使用Promise加载一张图片


function loadImg(src2) {
    
    
    return new Promise(
        //参数 resolve reject 均是函数
        (resolve,reject)=>{
    
    
            const img1 = document.createElement('image')
            img1.src = src2
            img1.onload=()=>{
    
    
                resolve(img1)
            }
            img1.onerror=()=>{
    
    
                const err = new Error(`图片加载失败!${
      
      src}`)
                reject(err)
            }
            
        }
    )
}
const url1 = 'https://img4.sycdn.imooc.com/szimg/5dbffa9109ef425a12000676-360-202.png'
const url2 = 'https://img4.sycdn.imooc.com/szimg/5dbffa9109ef425a12000676-360-202.png'
loadImg(url1).then(img=>{
    
    
    console.log(img.width)
    return img
}).then(img=>{
    
    
    console.log(img.height)
    return loadImg(url2)
}).then(img2=>{
    
    
    console.log(img2.width)
    return img2
}).then(img2=>{
    
    
    console.log(img2.height)
})
.catch(err=>{
    
    
    console.log(err)
})

异步应用的场景
  • 网络请求 , ajax 图片加载
  • 定时任务 ,如 setTimeout

在这里插入图片描述

小结

  • 单线程和异步,异步和同步区别
  • 前端异步的应用场景:网络请求 & 定时任务
  • Promise 解决 callback hell

JS 基础知识

回顾内容
内容
  • 变量的类型和计算
  • 原型和原型链
  • 作用域和闭包
  • 异步和单线程
回顾题目
变量类型和计算 - 题目
  • typeof 能判断哪些类型
  • 何时使用 === 何时使用 ====
  • 值类型和引用类型的区别
  • 手写深拷贝
回顾知识点
变量类型和计算 - 知识点
  • 值类型 VS 引用类型,堆栈模型,深拷贝
  • typeof 运算符
  • 类型转换, truly 和 falseiy 变量
原型和原型链 - 题目
  • 如何准确判断一个变量是不是数组
  • 手写一个简易的 jQuery,考虑插件和扩展性
  • class 的原型本质,怎么理解
原型和原型链 - 知识点
  • class 和继承,结合手写 jQuery 的示例来理解
  • instanceof
  • 原型和原型链:图示 & 执行规则
作用域和闭包 - 题目
  • this 的不同应用场景,如何取值
  • 手写 bind 函数
  • 实际开发中闭包的应用场景,举例说明
    在这里插入图片描述
作用域和闭包 - 知识点
  • 作用域和自由变量
  • 闭包:两种常见方式 & 自由变量查找规则
  • this
异步和单线程 - 题目
  • 同步和异步的区别是什么
  • 手写用 Promise 加载一张图片
    在这里插入图片描述
异步和单线程 - 知识点
  • 单线程和异步,异步和同步区别
  • 前端异步的应用场景:网络请求 & 定时任务
  • Promise 解决 callback hell

猜你喜欢

转载自blog.csdn.net/WLIULIANBO/article/details/114989059