ES6 提供的 Promise 方法和 ES7 提供的 Async/Await 语法糖都可以更好解决多层回调问题, 详细用法可参考:https://www.cnblogs.com/cckui/p/9915604.html,下面进一步介绍 promise 和 async/await 用法的异同。

首先定义以下三个异步函数:

function sleep3000() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('sleep3000 执行完成');
resolve(new Date());
}, 3000);
})
}; function sleep2000() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('sleep2000 执行完成');
resolve(new Date());
}, 2000);
})
};
function sleep4000() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log('sleep4000 执行完成');
resolve(new Date());
}, 4000);
})
};

1. 使用 promise 方法分别执行以上三个函数

console.log('Now:', new Date());

sleep3000().then((d) => {
console.log('3000:', d);
}) sleep2000().then((d) => {
console.log('2000:',d);
}) sleep4000().then((d) => {
console.log('2000:',d);
})

最终打印结果:

Now: 2019-04-08T02:29:38.388Z
sleep2000 执行完成
2000: 2019-04-08T02:29:40.398Z
sleep3000 执行完成
3000: 2019-04-08T02:29:41.398Z
sleep4000 执行完成
2000: 2019-04-08T02:29:42.394Z

2. 使用 promise.all() 方法

Promise 的 all() 方法提供了并行执行异步操作的能力,即在所有异步操作执行完后才执行回调, all()里面接收一个数组,数组中每个元素都返回一个 promise 对象。

all()里面的异步都执行完成后,才会把每个异步结果以数组的形式放入 then 中。

某些情况下,如果上面sleep3000、sleep200、sleep4000分别代表页面不同模块的加载时间,在页面刚打开时,需要当所有模块加载完成后,清除loading。此时可以作如下处理:

console.log('Now:', new Date());

Promise.all([
sleep2000(),
sleep3000(),
sleep4000()
]).then((res) => {
console.log(res)
})

最终打印结果:

Now: 2019-04-08T02:43:07.139Z
sleep2000 执行完成
sleep3000 执行完成
sleep4000 执行完成
[ 2019-04-08T02:43:09.144Z,
2019-04-08T02:43:10.145Z,
2019-04-08T02:43:11.144Z ]

3. 使用 promise.race() 方法

Promise 的 race() 方法 与 all () 相反,即只以执行最快的那个promise为准,一旦race()中的某个promise解决或拒绝,所有返回的 promise就会解决或拒绝。

console.log('Now:', new Date());

Promise.race([
sleep2000(),
sleep3000(),
sleep4000()
]).then((res) => {
console.log(res)
})

因为 sleep2000 最先执行完成,所以在2秒后,就会立即进入then。

最终打印结果:

Now: 2019-04-08T02:44:34.193Z
sleep2000 执行完成
2019-04-08T02:44:36.200Z
sleep3000 执行完成
sleep4000 执行完成

注意:2秒进入 then 后, sleep3000 和 sleep4000 并没有被停止, 仍会继续走完,只是不会处理resolve或reject。

4. async/await 处理以上三个函数

console.log('Now:', new Date());

async function getDate () {
let res1 = await sleep3000();
let res2 = await sleep2000();
let res3 = await sleep4000();
console.log('3000:', res1);
console.log('2000:', res2);
console.log('4000:', res3);
} getDate();

最终打印结果:

Now: 2019-04-08T02:58:23.990Z
sleep3000 执行完成
sleep2000 执行完成
sleep4000 执行完成
3000: 2019-04-08T02:58:26.996Z
2000: 2019-04-08T02:58:29.001Z
4000: 2019-04-08T02:58:33.004Z

通过打印时间,可见,每处理完前一个await,才会处理下一个await,上面所有处理完花费了9秒。

所以, 只有当处理后面await需要前一个await返回值时,才可以用以上方法。

5. async/await 中使用 promise.all 并行处理异步操作

当三个异步相互之间没有关系,需要同时发送时:

console.log('Now:', new Date());

async function getdate () {
let res1 = sleep3000();
let res2 = sleep2000();
let res3 = sleep4000();
let res = await Promise.all([res1, res2, res3]);
console.log(res);
} getdate();

最终打印结果:

sleep2000 执行完成
sleep3000 执行完成
sleep4000 执行完成
[ 2019-04-08T03:11:24.280Z,
2019-04-08T03:11:23.280Z,
2019-04-08T03:11:25.275Z ]

注意:

对比 2 和 5 的打印结果,可以看出,二者打印的返回数组里面的顺序是有区别的:

  • 只用promise.all()时,各个异步是无序的;
  • 在 async/await 中使用 promise.all(), 各个异步是有序的。

异步操作之 Promise 和 Async await 用法进阶的更多相关文章

  1. Promise 和async/await 的使用理解

    Promise 和async/await 的使用理解 1. new Promise时就会开始执行语句. new Promise(resolve => resolove('成功信息') )     ...

  2. 20分钟带你掌握JavaScript Promise和 Async/Await

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://www.freecodecamp.org/news/learn-promise-a ...

  3. Promise和async await详解

    本文转载自Promise和async await详解 Promise 状态 pending: 初始状态, 非 fulfilled 或 rejected. fulfilled: 成功的操作. rejec ...

  4. “setTimeout、Promise、Async/Await 的区别”题目解析和扩展

    解答这个题目之前,先回顾下JavaScript的事件循环(Event Loop). JavaScript的事件循环 事件循环(Event Loop):同步和异步任务分别进入不同的执行"场所& ...

  5. node.js异步控制流程 回调,事件,promise和async/await

    写这个问题是因为最近看到一些初学者用回调用的不亦乐乎,最后代码左调来又调去很不直观. 首先上结论:推荐使用async/await或者co/yield,其次是promise,再次是事件,回调不要使用. ...

  6. Promise, Generator, async/await的渐进理解

    作为前端开发者的伙伴们,肯定对Promise,Generator,async/await非常熟悉不过了.Promise绝对是烂记于心,而async/await却让使大伙们感觉到爽(原来异步可以这么简单 ...

  7. Promise及Async/Await

      一.为什么有Async/Await? 我们都知道已经有了Promise的解决方案了,为什么还要ES7提出新的Async/Await标准呢? 答案其实也显而易见:Promise虽然跳出了异步嵌套的怪 ...

  8. callback vs async.js vs promise vs async / await

    需求: A.依次读取 A|B|C 三个文件,如果有失败,则立即终止. B.同时读取 A|B|C 三个文件,如果有失败,则立即终止. 一.callback 需求A: let read = functio ...

  9. Callback, Promise和Async/Await的对比

    Callback, Promise和Async/Await的对比 Callback Hell getData1(function (data1) { console.log('我得到data1了') ...

随机推荐

  1. zxing开源库的基本使用

    如果你的项目中有模块跟二维码相关的话,那你一定听过或者用过大名鼎鼎的zxing开源库. 什么是zxing? ZXing是一个开源的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其 ...

  2. C#:读取视频的宽度和高度等信息

    读取方式:使用ffmpeg读取,所以需要先下载ffmpeg.网上资源有很多. 通过ffmpeg执行一条CMD命令可以读取出视频的帧高度和帧宽度信息. 如图: 蓝线框中可以看到获取到的帧高度和帧宽度. ...

  3. WPF:解决DataGrid横向滚动条无法显示的问题

    DataGrid的最后一列的宽度设置为“Width=”auto””即可. 如果显示指定长度或者设置为“*”,那么不管怎么拖动列头,或者不管行里面的内容有没有超过DataGrid的显示区域,DataGr ...

  4. Android 9.0更新

    北京时间2018年8月7日上午,Google 发布了 Android 9.0 操作系统.并宣布系统版本 Android P 被正式命名为代号"Pie". Android 9.0 利 ...

  5. 适配器Adapter

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2019/3/4 22:13 # @Author : ChenAdong # @emai ...

  6. [20180823]IMU与db link.txt

    [20180823]IMU与db link.txt --//当使用db link查看远程表时,实际上会产生小小的日志.--//当时如果与IMU结合在一起,可以导致IMU的失效. 1.环境:SCOTT@ ...

  7. 关于Box Anemometer的安装配置遇到的几个坑

    Box Anemometer是一个非常不错的MySQL慢查询可视化工具平台,具体就不多详述了,官网是https://github.com/box/Anemometer 最近动自己动手搭了一个,具体搭建 ...

  8. [UGUI]游戏中的Tips贴图标边缘显示(贴边)

    Tips贴图标边缘显示 图左:当左边宽度不足于容纳Tips时,Tips放在右侧显示,顶和图标对齐 图右:当左边宽度足够容纳Tips时,Tips放在左侧显示,顶和图标对齐 适应需求:当图标和Tips是在 ...

  9. cve-2017-11882 poc分析

    目录 CVE-2017-11882 poc分析 0x00 工具&实验环境 0x01 分析行为 第一步:观察poc行为 第二步:找出计算器被弹出的地方 0x02 调试定位漏洞触发点 0x03 分 ...

  10. 枚举应用demo

    package com.xx; public enum PositionEM{ ONE(1,"领导"), TWO(2,"员工"); private Long v ...