Javascript的异步与单线程

一、前言

我们都知道,javasript是一个单线程的语言;所谓单线程就是同一时间不能做两件事情,两段代码不能同时执行;因为这种机制,才避免了两段js同时对一个DOM节点进行渲染的冲突。但是也会因此产生一个问题,比如说有一个非常耗时的操作在js中执行,因为js是按顺序执行的,所以会导致代码一直卡在这个耗时的方法那里,从而造成页面假死的状态,为了解决这个问题,js也提供了一些解决方案,比 如Ajax、setTimeout、setInterval,提供了异步的解决方案。有人会说,那单线程和异步同时存在一个语言里不是冲突了吗?其实不然,js虽是单线程语言,但是浏览器不是单线程的啊,浏览器为js的执行分配了一个主线程,也可以通过某种方式另外开辟一个副线程去执行js中的耗时操作,然后通过callback的形式返回到主线程中去执行,所以说异步只是一种单线程的解决方案,并不能改变js语言作为一个单线程语言的本质。

二、异步

1、实现异步的方式(eventloop)事件轮询

eventloop即事件轮询,是js实现异步的具体方式,当js按顺序执行的时候遇到异步函数,会将异步函数放在异步队列中,当同步函数执行完毕之后会轮询执行异步队列中的函数。 

事件轮询会一直查询异步队列中是否存在异步函数,所以在第一个地步函数执行完成之后,等待了一秒之后会在异步队列中发现func2这个函数出现在异步队列中,于是事件轮询查询到这个函数,并将此函数放入主进程中执行。其中func1和func2均属于异步函数的回掉函数。

2、异步的几个解决方案

(1)jquery中的deffered

 1 function test() {
 2     var dt = $.Deferred()
 3     var wait = function(dt) {
 4         var task = function() {
 5             console.log(‘deffered is ok!‘)
 6             dt.resolve() //成功
 7             // dt.reject()  //失败
 8         }
 9         setTimeout(task, 1000)
10         return dt.promise()
11     }
12     return wait(dt)
13 }
14
15 var w = test()
16 // w.reject()    // 在这里执行reject()会导致接下来的函数走到error里,所以需要将上述返回对象改为返回promise
17 $.when(w).then(function() {
18     console.log(‘ok1‘)
19 }, function() {
20     console.log(‘error1‘)
21 })
22 w.then(function() {
23     console.log(‘ok2‘)
24 }, function() {
25     console.log(‘error2‘)
26 })

Deffered对象中可以主动修改resove或reject,promise只能被动监听

(2)Promise

Promise在ES6中真是被列为标准,关于Promise这里只说几个使用场景,

串联:即第二个异步的执行可能会依赖第一个异步执行的结果

 1 function loadImg(src) {
 2   var promise = new Promise((resolve, reject) => {
 3     var img = document.createElement(‘img‘)
 4     // throw new Error(‘this is a error!‘)  //抛出一个异常
 5     img.onload =function () {
 6       resolve(img)
 7     }
 8     img.onerror = function () {
 9       reject(‘picture onload error!‘) //传入一个信息会走到catch中捕捉到错误
10     }
11     img.src = src
12   })
13   return promise
14 };
15 //promise串联加载
16 var src = ‘**********************‘
17 var result = loadImg(src)
18 var src1 = ‘**********************‘
19 var result1 = loadImg(src1)
20
21 result.then(() => {
22   console.log(‘first‘)
23   return result1        // 此处返回result1Promise实例,若不返回则默认返回result
24 }).then(() => {
25   console.log(‘second‘)
26 }).catch((error) => {
27   console.log(error)
28 })

Promise.all传入一个数组,即当所有的一部函数全部执行完毕之后才会走的回调函数

1 Promise.all([result, result1]).then(function(res) {
2     // 全部执行完毕之后的逻辑
3 })

Promise.race同样传入一个数组,即只要有一个异步函数执行完毕之后都会走回调函数

1 Promise.race([result, result1]).then(function(res) {
2     // 全部执行完毕之后的逻辑
3 })

(3)async/await

此方法不在ES6标准中,ES7引入,还没有成为标准,相比于Promise它只是在执行回调的方式不同,其后面还是跟的一个Promise,只不过Promise后面的.then依旧使用的是异步的回调方式,而async则是使用同步的使用方式

1 const load = async function() {
2     const result = await loadImg(src)
3     console.log(result.width)
4     const result1 = await loadImg(src1)
5     console.log(result1.width)
6 }

以上为本次讨论内容,不足之处还请指正

原文地址:https://www.cnblogs.com/gaosong-shuhong/p/9280863.html

时间: 2024-10-12 01:34:32

Javascript的异步与单线程的相关文章

0182 JavaScript执行机制:单线程,同步任务和异步任务,执行栈,消息队列,事件循环

以下代码执行的结果是什么? [结果是1 2 3 ] console.log(1); setTimeout(function () { console.log(3); }, 1000); console.log(2); 以下代码执行的结果是什么? [结果是1 2 3 ] console.log(1); setTimeout(function () { console.log(3); }, 0); console.log(2); 1.3.1 JS 是单线程 单线程就意味着,所有任务需要排队,前一个任

JavaScript及其异步实现

由于javascript本身是单线程模型,这里主要通过Callbacks,Listeners,Control Flow Libraries ,Promises四种方式来实现异步操作. Reference:            1.JavaScript异步编程的四种方法(转)           2.JavaScript Promises 一.Callbacks(函数回调) 让我们首先以函数回调方式来开头,这种方式也是最基本,同时也是大家都知道的异步实现方法. 现在我们有两个函数:Functio

JavaScript 扯几句单线程相关

JavaScript 扯几句单线程相关 众所周知,Javascript是单线程执行的,这也就是说:JavaScript在同一个时间上只能处理一件事.他不像C,Java等这些多 线程的,可以开不同的线程去同时处理多件事情. 那么为什么别的语言都可以这么方便的去开多个线程去同时执行多个任务,JavaScript却不行呢? “天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行指乱其所为,所以动心忍性,曾益其所不能” --<孟子> 正是因为JavaScript背负着重大的使命,所以他只

理解Javascript的异步

前言 本文2925字,阅读大约需要10分钟. 总括: 本文梳理了异步代码和同步代码执行的区别,Javascript的事件循环,任务队列微任务队列等概念. 原文地址:Understanding Asynchronous JavaScript 公众号:「前端进阶学习」,回复「666」,获取一揽子前端技术书籍 未曾失败的人恐怕也未曾成功过. Javascript是单线程的编程语言,单线程就是说同一时间只能干一件事.放到编程语言上来说,就是说Javascript引擎(执行Javascript代码的虚拟机

对JavaScript中异步同步机制以及线程深入底层了解

今天在网上看到各种对Js异步同步单线程多线程的讨论 经过前辈们的洗礼 加上鄙人小小的理解 就来纸上谈兵一下吧~ Js本身就是单线程的 至于为什么Js是单线程的 那就要追溯到Js的历史了 总而言之 由于Js是浏览器的脚本语言 经常操作dom元素 多线程的话反而会导致更复杂(删除与添加同时进行?)这只是简单的解释了为什么Js要单线程的原因, 为什么Js又能异步执行方法呢? 这特么的不是很矛盾吗!!! 但是,但是注意了 就是因为Js主要是在浏览器中运行的脚本语言 浏览器是典型的GUi工作线程 因为它在

js异步和单线程

1.同步和异步的区别 a>同步会阻塞代码执行,异步不会 b>alert()是同步  setTimeout()是异步 2.关于setTimeout(); console.log(1); setTimeout(function() { console.log(2);}, 0); console.log(3); setTimeout(function() { console.log(4);}, 0); console.log(5); // 13524 3.前端执行异步的场景: a>定时任务 b

JavaScript中异步编程

一 关于事件的异步 事件是JavaScript中最重要的一个特征,nodejs就是利用js这一异步而设计出来的.所以这里讲一下事件机制. 在一个js文件中,如果要运行某一个函数,有2中手段,一个就是直接调用,比如foo(),第二就是利用事件来触发,这中函数也叫回调函数,比如传递给setTimeout函数和onready属性. 1.setTimeout函数中的事件异步 setTimeout本质上也是一种异步事件,当延迟时间到的时候触发该事件,但是有的有的时候(其实也是大部分时候)都不会按照给定的延

【转】javascript的异步概念

某天突然写了个方法要从后台调用数据,显示在前台页面,但是输出结果总是空 undefined,得不到数据.多方找资料才发现,原来是入了 JS 异步的 "坑". 我们常常听到单线程.多线程.同步.异步这些概念,那么这些东西到底是什么呢? 那么我们先从上面那几个概念说起 o( ̄▽ ̄) ブ 单线程.多线程.同步.异步基本理解 每个正在运行的程序(即进程)至少有一个线程,被称为主线程.主线程在启动程序时被创建,用于执行 main 函数. 单线程就是只有一个主线的线程,代码从上往下顺序运行,主线程

JavaScript的异步处理

Javascript语言的执行环境是"单线程"(single thread,就是指一次只能完成一件任务.如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推). 为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous). "同步模式" 就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的.同步的:"异步模式&quo