为什么会出现异步:

  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异步处理历程的更多相关文章

  1. JS魔法堂:深究JS异步编程模型

    前言  上周5在公司作了关于JS异步编程模型的技术分享,可能是内容太干的缘故吧,最后从大家的表情看出"这条粉肠到底在说啥?"的结果:(下面是PPT的讲义,具体的PPT和示例代码在h ...

  2. 纯js异步无刷新请求(只支持IE)

    纯js异步无刷新请求 下载地址:http://pan.baidu.com/s/1slakL1F 所以因为非IE浏览器都禁止跨域请求,所以以只支持IE. <HTML> <!-- 乱码( ...

  3. js异步编程

    前言 以一个煮饭的例子开始,例如有三件事,A是买菜.B是买肉.C是洗米,最终的结果是为了煮一餐饭.为了最后一餐饭,可以三件事一起做,也可以轮流做,也可能C需要最后做(等A.B做完),这三件事是相关的, ...

  4. C“中断” 与 JS“异步回调” 横向对比

    在底层C语言中,有一个非常重要而特别的概念,叫做“中断”.用比喻来说,我正在写着博客,突然我妈打个电话过来,我就离开了键盘去接电话了,然后写博客就中断了,我聊完电话回来再继续写.乍一听似乎并没有什么大 ...

  5. 利用ajaxfileupload.js异步上传文件

    1.引入ajaxfileupload.js 2.html代码 <input type="file" id="enclosure" name="e ...

  6. 深究JS异步编程模型

    前言  上周5在公司作了关于JS异步编程模型的技术分享,可能是内容太干的缘故吧,最后从大家的表情看出"这条粉肠到底在说啥?"的结果:(下面是PPT的讲义,具体的PPT和示例代码在h ...

  7. 点评js异步加载的4种方式

    主要介绍了点评js异步加载的4种方式,帮助大家更全面的了解js异步加载方式,感兴趣的小伙伴们可以参考一下 js异步加载的4种方式,点评开始. <!DOCTYPE html> <htm ...

  8. JS异步加载的三种方式

    js加载的缺点:加载工具方法没必要阻塞文档,过得js加载会影响页面效率,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作. 有些工具方法需要按需加载,用到再加载,不用不加载,. 默认正常 ...

  9. 关于JS异步加载方案

    javascript延迟加载的解决方案: 1.使用defer标签 <span style="font-size: small;"><script type=&qu ...

随机推荐

  1. linux使用"userdel 用户名“删除用户的解决办法

    在新建用户的时候我们可以忽略掉给用户分组的信息,而直接使用“useradd 用户名” 来直接添加新用户,所以由此想到删除用户能不能直接使用“userdel 用户名”来删除用户呢?回答是否定的,如此会残 ...

  2. .NET数据采集

    public string GetHttpData(string Url) { string sException = null; string sRslt = null; WebResponse o ...

  3. systemd的新特性及unit常见类型分析与awk用法示列

    简述systemd的新特性及unit常见类型分析,能够实现编译安装的如nginx\apache实现通过systemd来管理 系统引导的新特性 系统引导时实现服务启动: 按需激活进程: 系统状态快照: ...

  4. IDT表连接

    一.table A为基础表,左外连接table B,若要限制B的条件,需加(+),否则会对结果集以B表的条件进行过滤. DWD_REASON_CODE.CODE(+)=DWR_EDA_CL_TST_D ...

  5. 自己用的Xshell配色方案

    [comfort]text=dce2e2cyan(bold)=2ad1b8text(bold)=dce2e2magenta=dd3682green=55bb55green(bold)=55bb55ba ...

  6. Spark:将DataFrame写入Mysql

    Spark将DataFrame进行一些列处理后,需要将之写入mysql,下面是实现过程 1.mysql的信息 mysql的信息我保存在了外部的配置文件,这样方便后续的配置添加. //配置文件示例: [ ...

  7. php session的一些操作

    <?php /** * Session控制类 */ class Session{ /** * 设置session * @param String $name session name * @pa ...

  8. Django学习笔记之数据库-模型的操作

    模型的操作 在ORM框架中,所有模型相关的操作,比如添加/删除等.其实都是映射到数据库中一条数据的操作.因此模型操作也就是数据库表中数据的操作. 添加模型 添加模型到数据库中.首先需要创建一个模型.创 ...

  9. python selenium Chrome模拟手机浏览器(十七)

    在做移动端页面测试时可以利用Chrome mobile emulation 辅助完成页面的适配问题,但是目前手机市场上的型号居多我们也没有办法通过人工的模式一一的去适配,所以这里考虑到通过自动化的模式 ...

  10. 第七届蓝桥杯省赛javaB组 第七题剪邮票

    剪邮票 如[图1.jpg], 有12张连在一起的12生肖的邮票.现在你要从中剪下5张来,要求必须是连着的.(仅仅连接一个角不算相连)比如,[图2.jpg],[图3.jpg]中,粉红色所示部分就是合格的 ...