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. Android 消息异步处理之AsyncTask

    Android提供了异步处理消息的方式大致有两种,第一种是handler+Thread,之前已经对于这种方式做过分析,第二种就是AsyncTask,这是Android1.5提供的一种轻量级的工具类,其 ...

  2. 深入理解Java虚拟机02--Java内存区域与内存溢出异常

    一.概述 我们在进行 Java 开发的时候,很少关心 Java 的内存分配等等,因为这些活都让 JVM 给我们做了.不仅自动给我们分配内存,还有自动的回收无需再占用的内存空间,以腾出内存供其他人使用. ...

  3. git 入门教程之1分钟快速了解 git

    git 入门教程 git 是分布式版本控制系统,是文本文档管理的利器,是帮助你管理文件动态的好帮手. 如果你曾经手动管理过文档,一定有这样的经历,比如你正在编辑文档,想删除某段落,又担心不久后可能会恢 ...

  4. JAVA项目从运维部署到项目开发(一.Jenkins)

    一.Jenkins的介绍 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作, 旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. 二.功能 Jen ...

  5. 最近因为突然喜欢这方面的ui设计,所以搜刮了很多我试过可用性强的界面,又可爱又实用···分享给大家咯

    最近因为突然喜欢这方面的ui设计,所以搜刮了很多我试过可用性强的界面,又可爱又实用···分享给大家咯 1.Side-Menu.Android 分类侧滑菜单,Yalantis 出品. 项目地址:http ...

  6. Docker Data Center系列(三)- DTR安装指南

    本系列文章演示如何搭建一个mini的云平台和DevOps实践环境. 基于这套实践环境,可以部署微服务架构的应用栈,演练提升DevOps实践能力. 1 系统要求 1.1 硬件和软件要求 成为UCP管理的 ...

  7. Java代码优化总结(持续更新)

    1.对equals不熟 例子 if(user.get("s").equals("ss")){ //一堆代码 } 注:一旦前端页面传null值过来,就错了,nul ...

  8. perfect-scrollbar在vue中的使用

    1.下载perfect-scrollbar依赖包 npm install perfect-scrollbar 2.perfect-scrollbar特性 1)直接下载依赖包及包含css样式和js 2) ...

  9. springmvc复习笔记----springmvc姓名年龄例子:RequestParam 试水

    继续 继上节http://www.cnblogs.com/tk55/p/6652394.html 重要部分颜色突出 结构 包 web.xml 乱码处理方面设置 <url-pattern>* ...

  10. Spring MVC 请求映射 (二)

    完整的项目案例: springmvc.zip 目录 实例 项目结构: 一.配置web.xml <?xml version="1.0" encoding="UTF-8 ...