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 ...
随机推荐
- eclipse中 sec/test/resource 文件夹消失怎么设置?
右键改包--->build path --->Configure bulid path 按 add Folder 搞定.....
- iNeuOS工业互联平台,WEB组态(iNeuView)集成图报组件,满足实时数据图形化展示的需求
目 录 1. 概述... 1 2. 平台演示... 2 3. 应用过程... 3 4. 实时数据展示效果... 5 1. 概述 市场和开源社区有 ...
- TfidfVectorizer、CountVectorizer 和 TfidfTransformer 的简单教程
TfidfVectorizer.CountVectorizer 和 TfidfTransformer 是 sklearn 中处理自然语言常用的工具.TfidfVectorizer 相当于 CountV ...
- docker入门2-docker service
docker service介绍 service是生产环境中某个image的container集合.一个service只使用一个image,但它编排这个image的运行方式,比如使用哪个端口,根据需求 ...
- puppeteer去掉同源策略及请求拦截
puppeteer是一个功能强大的工具,在自动化测试和爬虫方面应用广泛,这里谈一下如何在puppeteer中关掉同源策略和进行请求拦截. 同源策略 同源策略为web 安全提供了有力的保障,但是有时候我 ...
- JS中new Date()用法及获取服务器时间
1.获取服务器时间: var now = new Date($.ajax({async: false}).getResponseHeader("Date")); 2.new Dat ...
- Java 8新的时间日期库,这二十个案例看完你还学不会算我的!!!
Java对日期,日历及时间的处理一直以来都饱受诟病,尤其是它决定将java.util.Date定义为可修改的以及将SimpleDateFormat实现成非线程安全的.看来Java已经意识到需要为时间及 ...
- C++入门记-大纲
缘来 由于某个不可告人的目标以及想趁着还有精力的年龄,开始了C++学习之路.C++ 诞生很多年了,但依然具有强大的生命力. 我们来看下2020年8月TIOBE 8 月编程语言排行榜. 可以看到C以及C ...
- XMLHttpRequest 简单封装
当开发简单页面的时候,不需要引入任何js库,这时需要封装一个用到 XMLHttpRequest 对象的好用的接口请求. simple 封装如下 ajaxRequest({ url: '', metho ...
- day44:CSS选择器优先级&JS基础
目录 1.CSS选择器优先级 2.补充:margin是可以设置百分比的 3.JS 3.1 js代码的引入方式 3.2 变量 3.3 数据类型 3.4 数组(类似于python中的列表) 3.5 自 ...