一、前言

我们都知道,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

 function test() {
var dt = $.Deferred()
var wait = function(dt) {
var task = function() {
console.log('deffered is ok!')
dt.resolve() //成功
// dt.reject() //失败
}
setTimeout(task, )
return dt.promise()
}
return wait(dt)
} var w = test()
// w.reject() // 在这里执行reject()会导致接下来的函数走到error里,所以需要将上述返回对象改为返回promise
$.when(w).then(function() {
console.log('ok1')
}, function() {
console.log('error1')
})
w.then(function() {
console.log('ok2')
}, function() {
console.log('error2')
})

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

(2)Promise

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

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

 function loadImg(src) {
var promise = new Promise((resolve, reject) => {
var img = document.createElement('img')
// throw new Error('this is a error!') //抛出一个异常
img.onload =function () {
resolve(img)
}
img.onerror = function () {
reject('picture onload error!') //传入一个信息会走到catch中捕捉到错误
}
img.src = src
})
return promise
};
//promise串联加载
var src = '**********************'
var result = loadImg(src)
var src1 = '**********************'
var result1 = loadImg(src1) result.then(() => {
console.log('first')
return result1 // 此处返回result1Promise实例,若不返回则默认返回result
}).then(() => {
console.log('second')
}).catch((error) => {
console.log(error)
})

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

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

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

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

(3)async/await

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

 const load = async function() {
const result = await loadImg(src)
console.log(result.width)
const result1 = await loadImg(src1)
console.log(result1.width)
}

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

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

  1. JavaScript 的异步和单线程

    问题 Q:下面的代码是否能满足sleep效果? var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert( ...

  2. JavaScript异步和单线程

    一,同步和异步的区别: 同步会阻塞代码执行,而异步不会.(比如alert是同步,setTimeout是异步) 二,前端使用异步的场景: 1,定时任务:setTimeout,setInterval 2, ...

  3. 【前端知识体系-JS相关】深入理解JavaScript异步和单线程

    1. 为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. Jav ...

  4. JavaScript 异步和单线程

    JavaScript语言本身是单线程的,所以它自身不可能是异步.所谓单线程,就必然意味着:所有任务需要排队,前一个任务结束,才会执行后一个任务. 但js的宿主环境(比如浏览器,Node)是多线程的.宿 ...

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

    以下代码执行的结果是什么? [结果是1 2 3 ] console.log(1); setTimeout(function () { console.log(3); }, 1000); console ...

  6. JavaScript的异步机制

    我们经常说JS是单线程的,比如node.js研讨会上大家都说JS的特色之一是单线程的,这样使JS更简单明了,可是大家真的理解所谓JS的单线程机制吗?单线程时,基于事件的异步机制又该当如何 1 先看下两 ...

  7. JavaScript 扯几句单线程相关

    JavaScript 扯几句单线程相关 众所周知,Javascript是单线程执行的,这也就是说:JavaScript在同一个时间上只能处理一件事.他不像C,Java等这些多 线程的,可以开不同的线程 ...

  8. Javascript的异步和回调

    介绍JavaScript的一些同步.异步.单线程多线程,回调基本概念:https://segmentfault.com/a/1190000002999668

  9. javascript的异步编程

    同步与异步 介绍异步之前,回顾一下,所谓同步编程,就是计算机一行一行按顺序依次执行代码,当前代码任务耗时执行会阻塞后续代码的执行. 同步编程,即是一种典型的请求-响应模型,当请求调用一个函数或方法后, ...

随机推荐

  1. HTTP1.1新增了五种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 、 CONNECT

    200 (成功) 服务器已成功处理了请求. 通常,这表示服务器提供了请求的网页. 201 (已创建) 请求成功并且服务器创建了新的资源. 202 (已接受) 服务器已接受请求,但尚未处理. 203 ( ...

  2. Django中authenticate和login模块

    Django 提供内置的视图(view)函数用于处理登录和退出,Django提供两个函数来执行django.contrib.auth中的动作 : authenticate()和login(). 认证给 ...

  3. Swift4.0复习整数,浮点数,布尔值

    1.类型相互转换: Int(a) Float(b) let a = Bool(truncating: NSNumber(value: c)) 2.元组: let tuple: (Int, String ...

  4. 【linux学习笔记三】链接命令

    链接命令:ln link =============华丽的分割线============= ln又有软链接和硬链接 //硬链接特征(不建议创建硬链接) 1.拥有相同的i节点和存储block块,可以看做 ...

  5. 11点睛Spring4.1-Property Editor

    11.1 Propert Editor property editor是JavaBeans API的一项特性,用来字符和属性值之间的互相转换(如2014-03-02和Date类型的互相转换) spri ...

  6. docker 在 centos7.* 上的部署及问题解决

    最近尝试搭建docker 环境,其实个人是比较喜欢“菜鸟学习系列”的知识的,怎奈它的讲解是以Ubuntu为主的,最后找到一个搭建学习系列,感觉写的很好,主要是页面风格清晰明了,遂决定按照此教程学习搭建 ...

  7. 一文带你全面了解RxJava

    工作需要,刚好在学习 RxJava网络请求框架,网上搜了一些 关于RxJava 的教程,但都并不是很好理解,所幸最后找到了几篇有助于初学者了解 RxJava 的文章,于是结合自己的理解,重新整理成一篇 ...

  8. 洛谷 题解 UVA247 【电话圈 Calling Circles】

    [题意] 如果两个人互相打电话(直接或者间接),则说他们在同一个电话圈里.例如,\(a\)打给\(b\),\(b\)打给\(c\),\(c\)打给\(d\),\(d\)打给\(a\),则这四个人在同一 ...

  9. [转帖]HBase详解(很全面)

    HBase详解(很全面) very long story 简单看了一遍 很多不明白的地方.. 2018-06-08 16:12:32 卢子墨 阅读数 34857更多 分类专栏: HBase   [转自 ...

  10. Python yield 使用浅析【转】

    Python yield 使用浅析 IBM developerWorks 中国 : Open source IBM 开源 - IBM Developer 中国 (原 developerWorks 中国 ...