乐趣区

关于前端:JavaScript异步编程

目录

  • JavaScript 采纳单线程模式工作的起因
  • 单线程的劣势和弊病
  • 同步模式与异步模式

    • 同步模式
    • 异步模式
    • 同步模式 API 和异步模式 API 的特点
  • 实现 JavaScript 异步编程的几种形式

    • 回调函数 —— 所有异步编程计划的根基
    • Promise —— 更优的异步编程解决方案
    • Generator
    • async/await —— 异步操作的终极解决方案

JavaScript 采纳单线程模式工作的起因

最早 JavaScript 语言就是运行在浏览器端的语言,目标是 为了实现页面上的动静交互 。实现页面交互的外围就是DOM 操作,这就决定了它必须应用单线程模型,否则就会呈现很简单的线程同步问题。

假如在 js 中有多个线程一起工作,其中一个线程批改了这个 DOM 元素,同时另一个线程又删除了这个元素,此时浏览器就无奈明确该以哪个工作线程为准。所以为了防止线程同步的问题,从一开始,js就设计成了单线程的工作模式。

所以,js 是单线程工作模式,如果有多个工作,工作须要排队,一个一个顺次去执行。

单线程的劣势和弊病

  • 劣势:更平安,更简略
  • 弊病:效率低,有些能够同时执行的工作必须期待。如果两头有一个特地耗时的工作,其余的工作就要期待很长的工夫,会呈现假死的状况。

为了解决这种问题,js 有两种工作的执行模式:

同步模式(Synchronous)异步模式(Asynchronous)

同步模式与异步模式

同步模式

指的是代码的工作顺次执行,后一个工作必须期待前一个工作完结能力开始执行。程序的执行程序和代码的编写程序是完全一致的。在单线程模式下,大多数工作都会以同步模式执行。

console.log('global begin')
function bar () {console.log('bar task') 
}
function foo () {console.log('foo task')
    bar()}
foo()
console.log('global end')

// global begin
// foo task
// bar task
//global end

// 应用调用栈的逻辑

为了防止耗时函数让页面卡顿和假死,所以还有异步模式。

异步模式

该模式不会去期待这个工作的完结才开始下一个工作,都是开启过后就立刻往后执行下一个工作,此时异步线程会独自执行异步工作,耗时函数的后续逻辑会通过回调函数的形式定义,执行过后会将回调放到音讯队列中,js 主线程执行完工作过后会顺次执行音讯队列中的工作。这里要强调,js 是单线程的,浏览器不是单线程的,有一些 API 是有独自的线程去做的。

上面看一个简略的异步模式的例子:

console.log('global begin')
// 延时器
setTimeout(function timer1 () {console.log('timer1 invoke')
}, 1800)
// 延时器中又嵌套了一个延时器
setTimeout(function timer2 () {console.log('timer2 invoke')
    setTimeout(function inner () {console.log('inner invoke')
    }, 1000)
}, 1000)
console.log('global end')

// global begin
// global end
// timer2 invoke
// timer1 invoke
// inner invoke

// 除了调用栈,还用到了音讯队列和事件循环

异步模式对于 JavaScript 语言十分重要,没有它就无奈同时解决大量的耗时工作。对于开发者而言。单线程上面的异步最大的难点就是 代码执行的程序凌乱,所以面试题外面百分百会考这里的内容 - -|||

同步模式 API 和异步模式 API 的特点

同步模式的 API 的特点:工作执行完代码才会持续往下走,例如:console.log

异步模式的 API 的特点:下达这个工作开启的指令之后代码就会继续执行,代码不会期待工作的完结

实现 JavaScript 异步编程的几种形式

回调函数 —— 所有异步编程计划的根基

回调函数:由调用者定义,交给执行者执行的函数

// callback 就是回调函数
// 就是把函数作为参数传递,毛病是不利于浏览,执行程序凌乱。function foo(callback) {setTimeout(function(){callback()
    }, 3000)
}

foo(function() {console.log('这就是一个回调函数')
    console.log('调用者定义这个函数,执行者执行这个函数')
    console.log('其实就是调用者通知执行者异步工作完结后应该做什么')
})

还有其余的一些实现异步的形式,例如:事件机制和公布订阅。这些也都是基于回调函数之上的变体。

Promise —— 更优的异步编程解决方案

次要为了解决回调天堂问题,具体理解参考 Promise(更优的异步编程解决方案)

Generator

具体理解参考 Generator -> Generator 异步计划

async/await —— 异步操作的终极解决方案

具体理解参考 async&await -> async/await 解决多回调异步

退出移动版