为什么会出现异步:

  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

最新文章

  1. pip 与pip3
  2. 利用DotSpatial发布WMS, WFS服务
  3. ADB简单基础命令
  4. KMP快速字符串匹配
  5. pbfunc外部函数扩展应用-直接在Datawindow中生成QR二维码,非图片方式
  6. Java JNI 编程进阶 实例+c++数据类型与jni数据类型转换
  7. windows下不打开浏览器访问网页的方法
  8. CAS实现无锁模式
  9. ajax请求,请求头是provisional are shown。请求未发送出去
  10. Android中半透明Activity效果另法
  11. HttpApplication实战大文件上传 (第四篇)
  12. Linux history命令
  13. JSON File Parse
  14. JS 实现兼容IE图片向左或向右翻转
  15. 用nodejs搭建BS环境
  16. Java反射之如何判断类或变量、方法的修饰符(Modifier解析)
  17. Building and using plug-ins for Android
  18. idea不识别yml配置文件,怎么办?
  19. sql 锁
  20. 多媒体基础知识之PCM数据

热门文章

  1. postman Could not get any response。
  2. 自动化测试_Mac安装python+selenium
  3. 不同组的id列表的汇总对比
  4. K-means算法应用:图片压缩
  5. 移动端单位rem计算
  6. 将 windows 目录结构 复制到 linux 上
  7. 在windows上编译apr库
  8. Java高级特性 第8节 网络编程技术
  9. rocketmq 4.3.2 解决远程不能消费问题,解决未识别到公网IP问题
  10. abstract class VS interface