js异步处理历程
为什么会出现异步:
js执行环境是单线程的,异步处理就非常重要。
处理的方法:
方法一:callback hell
解决:解决了异步处理
存在问题:出现多个回调函数嵌套,代码就会比较乱,出现回调地狱现象
方法二:Promise
解决:Promise的写法只是回调函数的改进,使用then方法,只是让异步任务的两段执行更清楚而已。
存在问题:Promise的最大问题是代码冗余,请求任务多时,一堆的then,也使得原来的语义变得很不清楚。
方法三:Generator
特征:有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态。
理解:
调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象,必须调用遍历器对象的next方法,使得指针移向下一个状态。
也就是说,每次调用next方法,内部指针就从函数头部或上一次停下来的地方开始执行,直到遇到下一个yield表达式(或return语句)为止。
换言之,Generator 函数是分段执行的,yield表达式是暂停执行的标记,而next方法可以恢复执行
解决:Generator函数的机制更符合我们理解的异步编程思想
存在问题:流程管理却不方便
方法四:async/await
解决:ES8引入了async函数,使得异步操作变得更加方便。简单说来,它就是Generator函数的语法糖。
——————————————————
需求一:利用上面四种方法完成需求:
图片一加载完之后加载图片二,
图片二加载完之后加载图片三,
图片三加载完之后加载图片四;
图片地址:
url1 = 'http://es6.ruanyifeng.com/images/cover_thumbnail_3rd.jpg';
url2 = 'http://pic22.nipic.com/20120621/1628220_155636709122_2.jpg';
url3 = 'http://file27.mafengwo.net/M00/5E/6E/wKgB6lPrJiiAFqFIAA1ZCe9u3vo07.jpeg';
url4 = 'http://img2.imgtn.bdimg.com/it/u=1198844836,3147847928&fm=26&gp=0.jpg';
方法一:callback hell
function getImage(url,success,fail){
let img = document.createElement('img');
img.src = url;
img.onload = function () {
success(img);
}
img.onerror = function () {
fail();
}
}
//加载图片一
getImage(url1,(img)=>{
console.log('图片一',img.width);
//加载图片二
setTimeout(()=>{
getImage(url2,(img)=>{
console.log('图片二',img.width);
//加载图片三
setTimeout(()=>{
getImage(url3,(img)=>{
console.log('图片三',img.width);
//加载图片四
setTimeout(()=>{
getImage(url4,(img)=>{
console.log('图片四',img.width);
})
},100)
})
},100)
})
},100)
},()=>{
console.log('失败')
})
方法二:Promise
function getImage(url) {
return new Promise((resolve,reject)=>{
let img = document.createElement('img');
img.src = url;
img.onload = function () {
resolve(img);
}
img.onerror = function () {
reject();
}
})
}
//方法一:
getImage(url1).then((img)=>{
console.log('图片一',img.width);
setTimeout(()=>{
getImage(url2).then((img)=>{
console.log('图片二',img.width);
setTimeout(()=>{
getImage(url3).then((img)=>{
console.log('图片三',img.width);
setTimeout(()=>{
getImage(url4).then((img)=>{
console.log('图片四',img.width);
});
},100)
});
},100)
});
},100)
}).catch(()=>{
console.log('失败')
})
//方法二:
getImage(url1).then((img)=>{
console.log('图片一',img.width);
return getImage(url2)
}).then((img)=>{
console.log('图片二',img.width)
return getImage(url3)
}).then((img)=>{
console.log('图片三',img.width)
return getImage(url4)
}).then((img)=>{
console.log('图片四',img.width)
}).catch(()=>{
console.log('失败')
})
方法三:Generator
function getImage(url) {
return new Promise((resolve,reject)=>{
let img = document.createElement('img');
img.src = url;
img.onload = function () {
resolve(img);
}
img.onerror = function () {
reject();
}
})
}
function * getUrl() {
yield getImage(url1).then((img)=>{
console.log('图片一',img.width);
});
yield getImage(url2).then((img)=>{
console.log('图片二',img.width);
});
yield getImage(url3).then((img)=>{
console.log('图片三',img.width);
});
return getImage(url4).then((img)=>{
console.log('图片四',img.width);
});
}
var gU = getUrl();
//存在问题:为什么不是按照顺序打印的?
gU.next();
gU.next();
gU.next();
gU.next();
方法四:async/await
function getImage(url) {
return new Promise((resolve,reject)=>{
let img = document.createElement('img');
img.src = url;
img.onload = function () {
resolve(img);
}
img.onerror = function () {
reject();
}
})
}
document.onclick = async function() {
//捕获错误的情况
try{
let img1 = await getImage(url1)
console.log(img1.width);
let img2 = await getImage(url2)
console.log(img2.width)
let img3 = await getImage(url3)
console.log(img3.width)
let img4 = await getImage(url4)
console.log(img4.width)
}catch (e) {
console.log('图一加载失败');
}
}
——————————————————
需求二:利用Promise和async完成需求:
图片一、二、三加载完之后加载图片四;
方法一:Promise
function getImage(url) {
return new Promise((resolve,reject)=>{
let img = document.createElement('img');
img.src = url;
img.onload = function () {
resolve(img);
}
img.onerror = function () {
reject();
}
})
}
Promise.all([getImage(url1),getImage(url2),getImage(url3)]).then((imgUrl)=>{
console.log(imgUrl);
imgUrl.forEach((item)=>{
console.log(item.width)
})
getImage(url4).then((img)=>{
console.log('图片四',img.width);
})
})
方法二:async/await
function getImage(url) {
return new Promise((resolve,reject)=>{
let img = document.createElement('img');
img.src = url;
img.onload = function () {
resolve(img);
}
img.onerror = function () {
reject();
}
})
}
document.onclick = async function() {
//捕获错误的情况
try{
let imgUrl = await Promise.all([getImage(url1),getImage(url2),getImage(url3)]);
imgUrl.forEach((item)=>{
console.log(item.width)
})
let img4 = await getImage(url4)
console.log(img4.width)
}catch (e) {
console.log('加载失败');
}
}
参考文章:https://blog.csdn.net/web_csdn_share/article/details/80094779
js异步处理历程的更多相关文章
- JS魔法堂:深究JS异步编程模型
前言 上周5在公司作了关于JS异步编程模型的技术分享,可能是内容太干的缘故吧,最后从大家的表情看出"这条粉肠到底在说啥?"的结果:(下面是PPT的讲义,具体的PPT和示例代码在h ...
- 纯js异步无刷新请求(只支持IE)
纯js异步无刷新请求 下载地址:http://pan.baidu.com/s/1slakL1F 所以因为非IE浏览器都禁止跨域请求,所以以只支持IE. <HTML> <!-- 乱码( ...
- js异步编程
前言 以一个煮饭的例子开始,例如有三件事,A是买菜.B是买肉.C是洗米,最终的结果是为了煮一餐饭.为了最后一餐饭,可以三件事一起做,也可以轮流做,也可能C需要最后做(等A.B做完),这三件事是相关的, ...
- C“中断” 与 JS“异步回调” 横向对比
在底层C语言中,有一个非常重要而特别的概念,叫做“中断”.用比喻来说,我正在写着博客,突然我妈打个电话过来,我就离开了键盘去接电话了,然后写博客就中断了,我聊完电话回来再继续写.乍一听似乎并没有什么大 ...
- 利用ajaxfileupload.js异步上传文件
1.引入ajaxfileupload.js 2.html代码 <input type="file" id="enclosure" name="e ...
- 深究JS异步编程模型
前言 上周5在公司作了关于JS异步编程模型的技术分享,可能是内容太干的缘故吧,最后从大家的表情看出"这条粉肠到底在说啥?"的结果:(下面是PPT的讲义,具体的PPT和示例代码在h ...
- 点评js异步加载的4种方式
主要介绍了点评js异步加载的4种方式,帮助大家更全面的了解js异步加载方式,感兴趣的小伙伴们可以参考一下 js异步加载的4种方式,点评开始. <!DOCTYPE html> <htm ...
- JS异步加载的三种方式
js加载的缺点:加载工具方法没必要阻塞文档,过得js加载会影响页面效率,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作. 有些工具方法需要按需加载,用到再加载,不用不加载,. 默认正常 ...
- 关于JS异步加载方案
javascript延迟加载的解决方案: 1.使用defer标签 <span style="font-size: small;"><script type=&qu ...
随机推荐
- JAVA第九次作业
JAVA第九次作业 (一)学习总结 1.用思维导图对javaIO操作的学习内容进行总结. 参考资料: XMind. 2.下面的程序实现了文件的拷贝,但采用的是一个字节一个字节的读写方式,效率很低.使用 ...
- 2018.8.8 SpringMVC分层
分层: 表示层:请求分发,调用处理器,页面展示. 业务层:业务处理接口和实现. 持久层:数据访问和持久化. 各层之间解耦,下层对上层透明. 具体代码分析如下图,图转自https://blog.csdn ...
- as 报错
报错: cantnot find the declaration of element 'LinearLayout' 解决: 原本为了解决报错我把Android support关掉了,然后百度到解决办 ...
- 入学java的第一天
登录http://www.oracle.com,下载JDK(J2SE) JDK 1.0,1.1,1.2,1.3,1.4 1.5(JDK5.0) 支持注解.支持泛型 1.6(JDK6.0)Server2 ...
- 机器学习基础一(TP,TN,FP,FN等)
TP:预测为正向(P),实际上预测正确(T),即判断为正向的正确率 TN:预测为负向(N),实际上预测正确(T),即判断为负向的正确率 FP:预测为正向(P),实际上预测错误(F),误报率,即把负向判 ...
- [C]最大公约数和最小公倍数
/*求最大公约数和最小公倍数 编写程序,在主函数中输入两个正整数 a,b,调用两个函数 fun1() 和 fun2(),分别求 a 和 b 的最大公约数和最小公倍数,在主函数中输出结果. */ #in ...
- 将TUM数据集的RGB-D数据集转化为klg格式
1.在github上下载代码png_to_klg git clone https://github.com/HTLife/png_to_klg 2.将png_to_klg目录下的associate.p ...
- Python map,filter,reduce函数
# -*- coding:utf-8 -*- #定义一个自己的map函数list_list = [1,2,4,8,16] def my_map(func,iterable): my_list = [] ...
- Centos7使用yum快速安装ansible
ansible功能简介:ansible可以实现批量系统配置.批量软件部署.批量文件拷贝.批量运行命令等功能.主要基于ssh实现连接各个被控制端 yum默认安装的ansible,常用的配置文件有两个,一 ...
- 3-Longest Substring Without Repeating Characters @LeetCode
3-Longest Substring Without Repeating Characters @LeetCode 题目 题目中得到的信息有: 一段字符串找出不重复子串的最大长度,只需要长度信息. ...