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

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

同步编程和异步编程

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

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

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

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

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

异步机制

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

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

事件循环

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

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

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

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

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

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

这样就能实现异步方式

js 的异步方式

  • setTimeout
  • ajax
  • Promise
  • Generator

setTimeout

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

setTimeout(() => {
console.log('Hello!')
}, 0)

ajax

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 解析及详解三个状态

const promise = new Promise(resolve => {
setTimeout(() => {
resolve('hello')
}, 1000)})
promise.then(value => {
console.log(value, 'world')
}, error =>{
console.log(error, 'unhappy')
})

Generator

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

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

JavaScript 异步编程的更多相关文章

  1. JavaScript异步编程的主要解决方案—对不起,我和你不在同一个频率上

    众所周知(这也忒夸张了吧?),Javascript通过事件驱动机制,在单线程模型下,以异步的形式来实现非阻塞的IO操作.这种模式使得JavaScript在处理事务时非常高效,但这带来了很多问题,比如异 ...

  2. JavaScript异步编程原理

    众所周知,JavaScript 的执行环境是单线程的,所谓的单线程就是一次只能完成一个任务,其任务的调度方式就是排队,这就和火车站洗手间门口的等待一样,前面的那个人没有搞定,你就只能站在后面排队等着. ...

  3. javascript异步编程的前世今生,从onclick到await/async

    javascript与异步编程 为了避免资源管理等复杂性的问题, javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是为 ...

  4. JavaScript异步编程(2)- 先驱者:jsDeferred

    JavaScript当前有众多实现异步编程的方式,最为耀眼的就是ECMAScript 6规范中的Promise对象,它来自于CommonJS小组的努力:Promise/A+规范. 研究javascri ...

  5. Promises与Javascript异步编程

    Promises与Javascript异步编程 转载:http://www.zawaliang.com/2013/08/399.html 在如今都追求用户体验的时代,Ajax应用真的是无所不在.加上这 ...

  6. 5分种让你了解javascript异步编程的前世今生,从onclick到await/async

      javascript与异步编程 为了避免资源管理等复杂性的问题,javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是 ...

  7. 转: Promises与Javascript异步编程

    在如今都追求用户体验的时代,Ajax应用真的是无所不在.加上这些年浏览器技术.HTML5以及CSS3等的发展,越来越多的富Web应用出现:在给与我们良好体验的同时,Web开发人员在背后需要处理越来越多 ...

  8. JavaScript异步编程

    前言 如果你有志于成为一个优秀的前端工程师,或是想要深入学习JavaScript,异步编程是必不可少的一个知识点,这也是区分初级,中级或高级前端的依据之一.如果你对异步编程没有太清晰的概念,那么我建议 ...

  9. 深入解析Javascript异步编程

    这里深入探讨下Javascript的异步编程技术.(P.S. 本文较长,请准备好瓜子可乐 :D) 一. Javascript异步编程简介 至少在语言级别上,Javascript是单线程的,因此异步编程 ...

  10. JavaScript 异步编程的前世今生(上)

    前言 提到 JavaScript 异步编程,很多小伙伴都很迷茫,本人花费大约一周的业余时间来对 JS 异步做一个完整的总结,和各位同学共勉共进步! 目录 part1 基础部分 什么是异步 part2 ...

随机推荐

  1. 微信小程序对接通联支付

    1.首先拿到通联支付开发API:https://aipboss.allinpay.com/know/devhelp/main.php?pid=15#mid=92 2.如果注册通联或者企业认证工作请到: ...

  2. 手动向Maven本地仓库添加ORACLE ojdbc6jar包

    第一步: 把你的oracle中的ojdbc6.jar复制放到D盘首目录 这是我的D:\oracle\product\11.2.0\dbhome_1\jdbc\ D:ojdbc6.jar 但是Maven ...

  3. Spring Boot 教程 - MyBatis-Plus

    1. Mybatis-Plus简介 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生. 为什么说Myba ...

  4. html表格、表单

    知识点一:表格 1.表格标签  table 2.表格的组成  行 tr  单元格  td 3.建立表格步骤 1.建立表格, 2.判断行数和列数 3.用行去包含单元格 4.在每个单元格中去添加内容 4. ...

  5. Spring源码阅读 ------------------- SpringFrameWork 5.2 +IDEA 部署

    Spring作为JAVA学习者的必须学习和熟悉的框架,需要理解Spring的设计原理,核心设计模式,对于理解设计模式,面向对象的深入理解有着深远持久的影响,特此首先要做到本地部署源码开始,下面将介绍如 ...

  6. 记一次 gltf 模型的绘制性能提升:从ppt到dove,丝滑感受

    转换思路 同样一个模型,分别取如下转换思路: 原始模型fbxgltf 原始模型objgltf 但是我在打开中间格式fbx和obj时,发现这两者虽然顶点数量一致,三角形数量一致,但是使用 Windows ...

  7. 构造vlan报文

    #!/usr/bin/python from scapy.all import * packet = Ether(src='dc:99:14:01:a3:5e', dst='ff:ff:ff:ff:f ...

  8. gorilla/mux 的学习

    原文链接:gorilla/mux的学习 源代码: package main import ( "encoding/json" "fmt" "githu ...

  9. ZK的watch机制

    1.watcher原理框架 由图看出,zk的watcher由客户端,客户端WatchManager,zk服务器组成.整个过程涉及了消息通信及数据存储. zk客户端向zk服务器注册watcher的同时, ...

  10. Mysql安装错误

    [问题一]在安装mysql时遇到以下错误 执行./mysqld --initialize 后 ./bin/mysqld: error while loading shared libraries: l ...