JavaScript 异步编程
博客地址: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 异步编程的更多相关文章
- JavaScript异步编程的主要解决方案—对不起,我和你不在同一个频率上
众所周知(这也忒夸张了吧?),Javascript通过事件驱动机制,在单线程模型下,以异步的形式来实现非阻塞的IO操作.这种模式使得JavaScript在处理事务时非常高效,但这带来了很多问题,比如异 ...
- JavaScript异步编程原理
众所周知,JavaScript 的执行环境是单线程的,所谓的单线程就是一次只能完成一个任务,其任务的调度方式就是排队,这就和火车站洗手间门口的等待一样,前面的那个人没有搞定,你就只能站在后面排队等着. ...
- javascript异步编程的前世今生,从onclick到await/async
javascript与异步编程 为了避免资源管理等复杂性的问题, javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是为 ...
- JavaScript异步编程(2)- 先驱者:jsDeferred
JavaScript当前有众多实现异步编程的方式,最为耀眼的就是ECMAScript 6规范中的Promise对象,它来自于CommonJS小组的努力:Promise/A+规范. 研究javascri ...
- Promises与Javascript异步编程
Promises与Javascript异步编程 转载:http://www.zawaliang.com/2013/08/399.html 在如今都追求用户体验的时代,Ajax应用真的是无所不在.加上这 ...
- 5分种让你了解javascript异步编程的前世今生,从onclick到await/async
javascript与异步编程 为了避免资源管理等复杂性的问题,javascript被设计为单线程的语言,即使有了html5 worker,也不能直接访问dom. javascript 设计之初是 ...
- 转: Promises与Javascript异步编程
在如今都追求用户体验的时代,Ajax应用真的是无所不在.加上这些年浏览器技术.HTML5以及CSS3等的发展,越来越多的富Web应用出现:在给与我们良好体验的同时,Web开发人员在背后需要处理越来越多 ...
- JavaScript异步编程
前言 如果你有志于成为一个优秀的前端工程师,或是想要深入学习JavaScript,异步编程是必不可少的一个知识点,这也是区分初级,中级或高级前端的依据之一.如果你对异步编程没有太清晰的概念,那么我建议 ...
- 深入解析Javascript异步编程
这里深入探讨下Javascript的异步编程技术.(P.S. 本文较长,请准备好瓜子可乐 :D) 一. Javascript异步编程简介 至少在语言级别上,Javascript是单线程的,因此异步编程 ...
- JavaScript 异步编程的前世今生(上)
前言 提到 JavaScript 异步编程,很多小伙伴都很迷茫,本人花费大约一周的业余时间来对 JS 异步做一个完整的总结,和各位同学共勉共进步! 目录 part1 基础部分 什么是异步 part2 ...
随机推荐
- VUE——添加组件模块(图表)
Vue是由一个个小模块组成的,模块可以让页面简介还可以复用: 1.不固定数据数量传到子组件 父组件: <chartVue v-for="(item, index) in chartLi ...
- 国人开源了一款小而全的 Java 工具类库,厉害啊!!
最近栈长看到了一款小而全的 Java 工具类库:Hutool,Github 已经接近 14K Star 了,想必一定很优秀,现在推荐给大家,很多轮子不要再造了! Hutool 是什么 Hutool 是 ...
- Spring Boot系列(二):Spring Boot自动装配原理解析
一.Spring Boot整合第三方组件(Redis为例) 1.加依赖 <!--redis--> <dependency> <groupId>org.springf ...
- 正规式转化为DFA
https://www.bilibili.com/video/BV1dj411f7AR?p=50 例题:
- Redis哨兵模式的配置
绪论 现有三台设备,192.168.137.11.192.168.137.12和192.168.137.13,要求在三台设备上实现redis哨兵模式,其中192.168.137.11为master,其 ...
- Jmeter 常用函数(4)- 详解 __setProperty
如果你想查看更多 Jmeter 常用函数可以在这篇文章找找哦 https://www.cnblogs.com/poloyy/p/13291704.html 前言 有看我之前写的 Jmeter 文章的童 ...
- CSS动画实例:移动的眼珠子
适当地利用CSS的box-shadow可以构造图形,然后可以对构造的图形添加动画效果.下面我们通过移动的眼珠子.圆珠一二三.一分为四.四小圆旋转扩散等实例来体会box-shadow属性在动画制作中的使 ...
- golang基础结构
1.命名 Go语言中的函数名.变量名.常量名.类型名.语句标号和包名等所有的命名,都遵循一个简单的命名规则:一个名字必须以一个字母(Unicode字母)或下划线开头,后面可以跟任意数量的字母.数字或下 ...
- Java树形结构中根据父类节点查找全部子类节点
上一篇文章介绍了两种树形结构数据整合json格式的方法,第一种方法中有根据父类获取全部子类的方法,这里单独拿出来再说一下. 仍然是利用递归来整合,代码如下: //根据父节点获取全部子节点 public ...
- IntelliJ IDEA下git版本回退,版本还原
原文链接:https://blog.csdn.net/hehyyoulan/article/details/80005272