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 ...
随机推荐
- MySQL基本操作——1
1.命令行启动或关闭MySQL服务:方式一:计算机--右击管理--服务方式二:net start MySQL服务器名称net stop MySQL服务器名称 2.登录和退出(必须在MySQL服务启动的 ...
- Python初学之使用方法修改字符串的大小写
对于字符串,可执行的最简单的操作之一是修改其中单词的大小写. titile()以首字母大写的方式显示每个单词,即将每个单词的首字母都改为大写: name.py name = "linda l ...
- git 入门教程
git 入门教程之协同开发 前面我们已经介绍过远程仓库的相关概念,不过那时并没有深入探讨,只是讲解了如何创建远程仓库以及推送最新工作成果到远程仓库,实际上远程仓库对于团队协同开发很重要,不仅仅是团队协 ...
- Python变量和常量
1.什么是变量 变量:核心在于变和量儿字,变->变化,量->状态如何定义? x=1 变量名 变量赋值符号:= 变量值:1 其中变量名又称为标识符: 1. 可以是字母,数字,下划线的任意组合 ...
- 顺序栈代码实现&&stack库
#include<iostream> using namespace std; ; typedef int Elemtype; struct SqStack { Elemtype *bas ...
- api接口的记录
http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.billboard.billList&type=1& ...
- 常规DP专题练习
POJ2279 Mr. Young's Picture Permutations 题意 Language:Default Mr. Young's Picture Permutations Time L ...
- ruoyi管理系统建立子项目,卡住
这个一定不要勾选,不然依赖加了还是引用不到.
- Linux col命令详解
Linux col命令 Linux col命令用于过滤控制字符. 在许多UNIX说明文件里,都有RLF控制字符.当我们运用shell特殊字符">"和">> ...
- Handlebars.js registerHelper
Handlebars.registerHelper('link', function (text, url) { text = Handlebars.Utils.escapeExpression(te ...