前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript 异步编程

JavaScript 异步编程

原创
作者头像
Krry
修改2020-09-15 18:10:35
5810
修改2020-09-15 18:10:35
举报
文章被收录于专栏:KrryblogKrryblog

博客地址:https://ainyi.com/96

众所周知,JavaScript 是单线程的,但异步在 js 中很常见,那么简单来介绍一下异步编程

同步编程和异步编程

同步编程,计算机一行一行按顺序依次执行代码,当前代码任务执行时会阻塞后续代码的执行;典型的请求-响应模型就是这样,当请求调用一个函数或方法后,需等待其响应返回,然后执行后续代码

异步编程,执行当前任务时(执行中),也可直接执行下一个任务;多个任务并发执行

这就涉及到两个比较容易混淆的概念了:并行并发

并行(parallel):指同一时刻内多任务同时进行;如下图:

755737372912ea8e89c4007.jpg
755737372912ea8e89c4007.jpg

并发(concurrency):指在同一时间段内,多任务同时进行着,但是同一时刻,只有某一任务执行。使得在宏观上具有多个进程同时执行的效果,但在微观上只是把时间分成若干段,使多个进程快速交替地执行;如下图:

7557373da64ffd6d1effaac.jpg
7557373da64ffd6d1effaac.jpg

异步机制

由上面并发的解释,可以知道单线程可以实现类似多线程机制的这种执行方式;那么 JavaScript 单线程的异步编程可以实现多任务==并发执行==

重点实现 js 异步的方式,就是==事件循环==,之前写过关于事件循环的例子,可看:JavaScript 事件循环、异步和同步

事件循环

事件循环涉及到两个概念:消息队列、任务

消息队列:也叫任务队列,存储待处理消息及对应的回调函数或事件处理程序

任务:js 区分同步任务和异步任务,代码执行就是在执行任务,也就是对应同步和异步的代码块

首先 JavaScript 的同步任务是进入主线程的执行栈执行;异步任务则进入==消息队列(任务队列)==,一个存储着待执行任务的队列,严格按照时间先后顺序执行,排在队头的任务将会率先执行,而排在队尾的任务会最后执行

事件循环的流程:检查主线程执行栈是否为空,先执行执行栈中的同步任务,异步任务(回调函数)放入任务队列中,一旦执行栈中的所有的同步任务执行完毕,就会取出任务队列的首部压入执行栈,开始执行,然后继续检查执行栈是否为空,重复这个过程

简单来说:事件循环其实就是入栈出栈的循环

这样就能实现异步方式

js 的异步方式

  • setTimeout
  • ajax
  • Promise
  • Generator

setTimeout

即使将时间设置为 0,也会延迟执行,即异步执行。具体可看:setTimeout 时间参数为 0 的探讨

代码语言:txt
复制
setTimeout(() => { 
   console.log('Hello!')
}, 0)

ajax

代码语言:txt
复制
let xhr = new XMLHttpRequest()
xhr.onreadystatechange = function() { 
  if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 ) {       
    console.log(xhr.responseText)
  } else {   
    console.log( xhr.status)
  }
}
xhr.open('GET', 'url', false)
xhr.send()

xhr.open 中第三个参数默认为 false 异步执行,改为 true 时为同步执行

Promise

promise 就经常使用了,平常使用 axios 作为请求接口的方式,就是封装了 Promise。当然也可以自己封装使用

具体可看:ES6 Promise 解析及详解三个状态

代码语言:txt
复制
const promise = new Promise(resolve => {
  setTimeout(() => {
    resolve('hello')
  }, 1000)})
promise.then(value => {
  console.log(value, 'world')
}, error =>{
  console.log(error, 'unhappy')
})

Generator

generator 也叫做生成器,它是 ES6 中引入的一种新的函数类型,内部拥有能够多次启动和暂停代码执行的强大能力,那么也能够用于异步编程中

代码语言:txt
复制
const axios = require('axios')

const foo = function () {
  return axios({
    method: 'GET',
    url: 'https://cosmos-alien.com/some.url'
  })
}

const main = function *() {
  try {
    let result = yield foo()
    console.log(result)
  } catch (err) {
    console.error(err)
  }
}

let it = main()
let p = it.next().value

p.then((data) => {
  it.next(data)
}, (err) => {
  it.throw(err)
})

博客地址:https://ainyi.com/96

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 同步编程和异步编程
  • 异步机制
    • 事件循环
    • js 的异步方式
    相关产品与服务
    消息队列 CMQ 版
    消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一款分布式高可用的消息队列服务,它能够提供可靠的,基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的 CMQ 队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档