单线程

  只有一个线程,同一时间只能做一件事

  原因:避免DOM渲染的冲突

    浏览器需要渲染DOM

    JS可以修改DOM结果

    JS执行的时候,浏览器DOM渲染会暂停

    两段JS也不能同时执行(修改DOM就冲突)

    webworker支持多线程,但是不能访问DOM,本质JS还是单线程

  解决方案:异步

case1

{
var i, sum = 0
for(i = 0; i < 100000000; i++) {
sum += i
}
console.log(sum)
}

case2

{
console.log(1)
alert('a')
console.log(2)
}

分析:JS执行阻塞DOM渲染,出现卡顿。因为js是单线程

case3

{
console.log(100)
setTimeout(function(){
console.log(200)
},100)
console.log(300)
}

分析:JS是单线程的,第一行打印100,第二行setTimeout是异步,暂时不执行,先往下执行,第三行打印300,代码结束。然后发现setTimout没执行,那么打印200。

event-loop

  事件轮询,JS实现异步的具体解决方案

  同步代码,直接执行

  异步函数先放在异步队列中

  待同步函数执行完毕,轮询执行异步队列的函数

case1

{
console.log(100)
setTimeout(function(){
console.log(200)
},100)
console.log(300)
}

分析:同步代码,直接执行,第一行和第三行是同步代码,直接打印100和300,第二行是异步代码,先放入异步队列。同步代码执行完毕,这时候查看异步队列,执行setTimeout打印200

case2

{
console.log(100)
setTimeout(function(){
console.log(200)
},100)
setTimeout(function(){
console.log(300)
})
console.log(400)
}

分析:同步代码直接执行,第一行和第四行直接执行,打印100和400。

   同步代码执行完毕,查看异步队列。这时候有2个setTimeout函数,第三行会直接放入异步队列中,那么打印300。

   而第二行100ms之后才被放入异步队列中,打印200

case3

{
$.ajax({
url:'',
success:function(result){
console.log('a')
}
})
setTimeout(function(){
console.log('b')
},100)
setTimeout(function(){
console.log('c')
})
console.log('d')
}

结果: d c a b或者 d c b a

jQuery的Deferred

  dtd.resolve/dtd.reject

  dtd.then/dtd.done/dtd/fail

case1

function waitHandle() {
var dtd = $.Deferred()
!function(dtd){
var task = function() {
console.log('执行完毕')
dtd.resolve()
}
setTimeout(task, 2000)
}(dtd)
return dtd
} waitHandle()
.then(function(){
console.log('success')
})

case2

function waitHandle() {
var dtd = $.Deferred()
!function(dtd){
var task = function() {
console.log('执行完毕')
dtd.resolve()
}
setTimeout(task, 2000)
}(dtd)
return dtd.promise()
} var w = waitHandle()
$.when(w).then(function(){
console.log('success')
})

注意:这2个case不同之处一个case是返回dtd还有一个返回dtd.promise()对象。

   第一个case w.reject()不会报错,但是会出现代码混乱

   第二个case w.reject()会报错,无法干预代码

Promise

  回顾下语法

case

{
function loadImg(src){
return new Promise((resolve, reject)=>{
let img = document.createElement('img') img.onload = () => resolve(img) img.onerror = () => reject() img.src = src
})
} const src = 'https://....jpeg' var res = loadImg(src)
res.then(img => {
console.log(img)
}, () => {
console.log('fail')
})
}

异常捕获

  使用catch统一捕获异常

case

{
function loadImg(src){
return new Promise((resolve, reject)=>{
let img = document.createElement('img')
img.onload = () => resolve(img) img.onerror = () => reject('异常') img.src = src
})
} const src = 'https://....jpeg' var res = loadImg(src)
res.then(img => {
console.log(img)
}).catch(e => {
console.log(e)
})
}

多个串联

  链式操作部分代码

const res = loadImg(src)
const res2 = loadImg(src2)
res.then(() => {
console.log('one')
return res2
}).then(() => {
console.log('two')
}).catch(e => {
console.log(e)
})

Promise.all和Promise.race

  Promise.all接收一个promise对象的数组,待全部完成之后,统一执行then

  Promise.race接收一个promise对象的数组,只要一个完成,就执行then

async/await

  直接只用同步写法

case

{
function loadImg(src){
return new Promise((resolve, reject)=>{
let img = document.createElement('img')
img.onload = () => resolve(img) img.onerror = () => reject('异常') img.src = src
})
} const src = 'https://....jpeg'
const src2 = 'https://...jpg' async function load() {
const res = await loadImg(src)
console.log(res)
const res2 = await loadImg(src2)
console.log(res2)
}
load()
}

虽然是同步写法,但是使用了Promise,并没有改变JS时单线程,异步的本质

JS高级-异步的更多相关文章

  1. 惰性函数——JS高级

    我们先来看一下js的异步提交. XHR我们在原生的时候常常用到,因为常用到,我们更多把封装到了工具库中 先看下他最常用的实现 // 旧方法 function createXHR() { var xhr ...

  2. js的异步和单线程

    最近,同事之间做技术分享的时候提到了一个问题"js的异步是另开一个线程吗?"当时为此争论不休.会后自己查阅了一些资料,对这个问题进行一个自我的分析与总结,有不同意见的希望可以赐教, ...

  3. 《Node.js 高级编程》简介与第二章笔记

    <Node.js 高级编程> 作者简介 Pedro Teixerra 高产,开源项目程序员 Node 社区活跃成员,Node公司的创始人之一. 10岁开始编程,Visual Basic.C ...

  4. Ext.js高级组件

    第二章:Ext.js高级组件 grid组件 普通方式 表格面板类Ext.grid.Panel xtype(别名):gridpanel.grid title标题.renderTo渲染至.width宽.h ...

  5. JS高级(摘自简书)

    JS高级 1. 访问对象属性(方法也是属性)的通用方式:obj['属性名'] 1. 属性名包含特殊字符,如"-".空格,访问:obj['content-type'] 2. 属性名不 ...

  6. JS高级前端开发群加群说明及如何晋级

    JS高级前端开发群加群说明 一.文章背景: 二. 高级群: 三. 加入方式: 四. 说明:   一.文章背景: 去年年初建了几个群,在不经意间火了,一直排在“前端开发”关键字搜索结果第一名.当然取得这 ...

  7. 前端进阶试题css(来自js高级前端开发---豪情)既然被发现了HOHO,那我就置顶了嘿嘿!觉得自己技术OK的可以把这套题目做完哦,然后加入高级前端的社区咯

    http://www.cnblogs.com/jikey/p/4426105.html js高级前端开发加群方法(此群很难进,里面纯技术,严禁广告,水群) 完整题目做完发邮箱(jikeytang@16 ...

  8. Node.js高级编程读书笔记Outline

    Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...

  9. 读JS高级——第五章-引用类型 _记录

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

随机推荐

  1. 封装一个函数,在ThinkPHP中一定程度上取代success和error

    1.下载jq2.下载layer3.根据自己的项目配置,将上述2文件放到样式目录中4.在Application/Common/function.php中添加如下代码function msg($msg,$ ...

  2. 笨办法29IF语句

    people = 20 cats = 30 dogs = 15 if people < cats: print "Too many cats! The world is doomed! ...

  3. <转载> 从算法上解读自动驾驶是如何实现的?

     科技新闻小鹏汽车2016-03-28 10:42 [摘要]车辆路径规划问题中路网模型.路径规划算法和交通信息的智能预测为关键点. 由于驾驶员的驾驶工作繁重,同时随着汽车拥有量的增加,非职业驾驶员的数 ...

  4. 移动应用调试之Inspect远程调试

    移动应用调试之Inspect远程调试 一.准备工作 chrome浏览器,建议最新版本 如果你点击inspect打开的DevTools窗口一片空白,且刷新无效时,那极有可能是由于被墙的缘故. 二.Ins ...

  5. C#中用NPOI的excel导出

    //机构表导出 private static List<User2> amininf = new BLL.Bll().GetUser2s(); //定义数据源导出对象 #region 导出 ...

  6. Sed+Grep 快速替换查找字段(批量替换字符串)

    格式: sed -i "s/查找字段/替换字段/g" `grep 查找字段 -rl路径` 命令分解: grep 查找字段 -rl路径   列出”路径”中” 查找字段” 的所有文件 ...

  7. c#抓屏功能在DPI缩放后,截到的图片不完整的问题

    /// <summary> /// 获取屏幕快照 /// </summary> /// <returns></returns> public stati ...

  8. 剑指Offer 50. 数组中重复的数字 (数组)

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

  9. 2456 Aggressive cows

    Aggressive cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23866   Accepted: 11141 ...

  10. phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连接 解决办法

    phpMyAdmin 尝试连接到 MySQL 服务器,但服务器拒绝连接.您应该检查配置文件中的主机.用户名和密码,并确认这些信息与 MySQL 服务器管理员所给出的信息一致. 原因有可能是因为修改了m ...