使用 async / await, 搭配 promise, 可以通过编写形似同步的代码来处理异步流程, 提高代码的简洁性和可读性. 本文介绍 async / await 的基本用法和一些注意事项.

await

引用MDN的介绍:

await 操作符用于等待一个 Promise 对象, 它只能在异步函数 async function 内部使用.

await 的使用语法非常简单:

[return_value] = await expression;

其中 expression 是一个 Promise 对象或者任何要等待的值;

而 await expression 的执行结果有以下几种情况:

  1. 若 expression 是一个 Promise 对象, 并且其以值 x 被 fulfilled, 则返回值为 x.

  2. 若 expression 是一个 Promise 对象, 并且其以异常 e 被 rejected, 则抛出异常 e.

  3. 若 expression 不是 Promise 对象, 则会将 expression 处理成一个以 expression 值被 fulfilled 的 Promise 对象, 然后返回这个 Promise 对象的最终值 (即 expression 值). 这种用法没太大意义, 因此实际使用时还是尽量在 await 后跟一个 Promise 对象.

  4. 另外需要注意的是, await 在等待 Promise 对象时会导致 async function 暂停执行, 一直到 Promise 对象决议之后才会 async function 继续执行.

    通过一段代码来看一下:

async function foo() {
var a = await new Promise((resolve) => {
setTimeout(() => {
resolve(1);
}, 2000);
});
console.log(a); // 第2秒时输出: 1 try {
var b = await new Promise((resolve, reject) => {
setTimeout(() => {
reject(2);
}, 1000);
})
} catch (e) {
console.log(e); // 第3秒时输出: 2
} // 函数暂停2秒后再继续执行
var sleep = await new Promise((resolve) => {
setTimeout(() => {
resolve('sleep');
}, 2000);
}); var c = await 3;
console.log(c); // 第5秒时输出: 3
} foo();

  

async

使用 async function 可以定义一个 异步函数, 语法为:

async function name([param[, param[, ... param]]]) { statements }

async 函数的返回值很特殊: 不管在函数体内 return 了什么值, async 函数的实际返回值总是一个 Promise 对象. 详细讲就是:

若在 async 函数中 return 了一个值 x, 不管 x 值是什么类型, async 函数的实际返回值总是 Promise.resolve(x).

那么 Promise.resolve(x) 最终返回一个什么样的promise呢? 来看一下MDN的介绍:

Promise.resolve(value)方法返回一个以给定值解析后的Promise对象。但如果这个值是个thenable(即带有then方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态(指resolved/rejected/pending/settled);否则以该值为成功状态返回promise对象。

接下来看一段代码的应用. 假设有这样一个场景: 需要先通过 请求1 拿到 数据1, 然后通过通过 请求2 并携带发送 数据1 获取到 数据2, 拿到 数据2 之后再展示到页面.

方案一:

async function showData() {
// 假装请求数据1
var data1 = await new Promise((resolve) => {
setTimeout(() => {
resolve('data1');
}, 1000);
}); // 假装请求数据2且此请求依赖数据1
var data2 = await new Promise((resolve) => {
setTimeout(() => {
resolve('data2');
}, 1000);
}); // 展示数据2
console.log(data2);
} showData();

  

上面这段代码是依次获取到 数据1 和 数据2, 然后再展示 数据2.

既然 async 函数总是返回一个promise, 那么也可以在一个 async 函数返回获取 数据2 的promise, 调用函数后再使用 then方法拿到数据, 代码如下:

async function getData() {
// 假装请求数据1
var data1 = await new Promise((resolve) => {
setTimeout(() => {
resolve('data1');
}, 1000);
}); // 假装请求数据2且此请求依赖数据1
return new Promise((resolve) => {
setTimeout(() => {
resolve('data2');
}, 1000);
});
} getData().then((v) => {
console.log(v);
});

  转自:https://blog.csdn.net/juhaotian/article/details/78934097
https://segmentfault.com/a/1190000010244279

async/await的使用以及注意事项的更多相关文章

  1. async & await 异步编程的一点巧方法

    await 关键字不会创建新的线程,而是由Task任务或是FCL中的xxxAsync等方法创建的线程,而且这里创建的线程都是基于线程池创建的工作线程,属于后台线程. await关键字会阻塞/暂停调用它 ...

  2. async/await使用深入详解

    async和await作为异步模型代码编写的语法糖已经提供了一段时间不过一直没怎么用,由于最近需要在BeetleX webapi中集成对Task方法的支持,所以对async和await有了深入的了解和 ...

  3. Python 进阶 异步async/await

    一,前言 本文将会讲述Python 3.5之后出现的async/await的使用方法,我从上看到一篇不错的博客,自己对其进行了梳理.该文章原地址https://www.cnblogs.com/dhcn ...

  4. 异步编程之Async,Await和ConfigureAwait的关系

    在.NET Framework 4.5中,async / await关键字已添加到该版本中,简化多线程操作,以使异步编程更易于使用.为了最大化利用资源而不挂起UI,你应该尽可能地尝试使用异步编程.虽然 ...

  5. Async,Await和ConfigureAwait的关系

    [转自]https://mp.weixin.qq.com/s/h10V-FshGoaQUWFPfy-azg 在.NET Framework 4.5中,async / await关键字已添加到该版本中, ...

  6. 测试Promise与Async/await的基本使用

    想在项目中用, 发现自己不是很熟 promise基本使用 基本使用-思路 new Promise()返回了一个状态机 一个完全无法被外界影响的状态机 构造函数, 传入一个函数, 两个参数, 分别是re ...

  7. 异步编程新方式async/await

    一.前言 实际上对async/await并不是很陌生,早在阮大大的ES6教程里面就接触到了,但是一直处于理解并不熟练使用的状态,于是决定重新学习并且总结一下,写了这篇博文.如果文中有错误的地方还请各位 ...

  8. 温故知新,CSharp遇见异步编程(Async/Await),聊聊异步编程最佳做法

    什么是异步编程(Async/Await) Async/Await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁.易懂.易维护的异步代码. Async/Await是C# 5引入的关键字,用以 ...

  9. C#async\await组合

    一.概述 编译器提供的便捷功能,就是语法糖.我的理解是为了优化代码.被async修饰的函数被称之为异步函数,主要用于异步编程,着重于靠await实现回调机制. 二.声明 //async用在方法名之前 ...

随机推荐

  1. Unity 5.6中的混合光照(下)

    https://mp.weixin.qq.com/s/DNQFsWpZm-ybIlF3DTAk2A 在<Unity 5.6中的混合光照(上)>中,我们介绍了混合模式,以及Subtracti ...

  2. python的编码问题整理

    一.编码和解码 1.编码(encode):将人类可以识别的语言(英文.中文等)转化成机器语言(01串)的过程,用于存储. 2.解码(decode):将机器语言转化成人类可识别的语言的过程,用于显示. ...

  3. Luogu P1558 色板游戏【线段树/状态压缩】By cellur925

    题目传送门 今天非常想再看一遍霸王别姬想不进去题于是开始刷数据结构 注意到至多只有\(30\)种颜色,啊啊啊啊我一开始竟然想的不是状态压缩而是在线段树中存一个30大小的数组,这样每次更新的时候暴力循环 ...

  4. java基础第六篇之常用思想、封装、继承和多态

    a.累加求和思想:求1~100的和,求数组/集合中元素的和,求偶数的数,求总分 int sum=0//循环外部定义sum变量,循环里面对每个元素累加 for (; ; ) { //sum+=数据 } ...

  5. django-跨域访问

    pip install django-cors-headers #安装cors INSTALLED_APPS = [ ... 'corsheaders', ... ] MIDDLEWARE_CLASS ...

  6. CSS标签大全

    CSS常用标签 字体属性:(font) 大小:font-size: x-large;(特大) xx-small;(极小) 一般中文用不到,只要用数值就可以,单位:PX.PD 样式 :font-styl ...

  7. Middleware-请求管道的构成

    Middleware-请求管道的构成 在 ASP.NET 中,我们知道,它有一个面向切面的请求管道,有19个主要的事件构成,能够让我们进行灵活的扩展.通常是在 web.config 中通过注册 Htt ...

  8. 《java学习三》jvm性能优化-------调优

    常见参数配置 -XX:+PrintGC      每次触发GC的时候打印相关日志 -XX:+UseSerialGC      串行回收 -XX:+PrintGCDetails  更详细的GC日志 -X ...

  9. SPRING代理模式

    1.静态代理 主题对象:Student public interface Student { public String add(); } 目标对象:RealStudent public class ...

  10. sqlsever 判断某个字段出现重复的字母或字符

    -------下面使用标量值函数判断  出现重复的个数 create function fn_str_times(@str varchar(1000),--原子符串@indexstr varchar( ...