TyepScript入门教程 之 async await

涵盖相同内容的PRO Egghead视频课程

作为一个思想实验,可以设想以下内容:一种告诉JavaScript运行await时在对promise使用时暂停关键字上代码的执行,并且恢复一次(如果返回)从函数返回的promise的方式:

// Not actual code. A thought experiment
async function foo() {try {var val = await getMeAPromise();console.log(val);}catch(err) {console.log('Error: ', err.message);}
}

当承诺达成后,执行就会继续,

  • 如果完成,则等待将返回该值,
  • 如果拒绝,则会同步引发错误,我们可以捕获该错误。

这突然地(神奇地)使异步编程和同步编程一样容易。此思想实验所需的三件事是:

  • 暂停功能执行的能力。
  • 可以在函数内放置值
  • 能够在函数内部引发异常

这正是发电机允许我们做的!思想实验实际上是真实的,因此TypeScript / JavaScript中的asyncawait实现也是如此。在幕后,它仅使用生成器。

生成JavaScript

您不必理解这一点,但是如果您阅读了generators,这很简单。该函数foo可以简单地包装如下:

const foo = wrapToReturnPromise(function* () {try {var val = yield getMeAPromise();console.log(val);}catch(err) {console.log('Error: ', err.message);}
});

wrapToReturnPromise刚刚执行生成函数来获取generator,然后使用generator.next(),如果该值是promise它会thencatch的承诺,并根据结果调用generator.next(result)generator.throw(error)。而已!

TypeScript中的异步等待支持

从1.7版开始,TypeScript支持Async-Await。异步函数以async关键字为前缀;await暂停执行,直到完成异步函数返回诺言,并从返回的Promise中解包该值。仅支持将目标 es6直接移植到ES6生成器

TypeScript 2.1 在ES3和ES5运行时中添加了此功能,这意味着无论使用什么环境,您都可以自由地利用它。重要的是要注意,我们可以在TypeScript 2.1中使用async / await,并且支持许多浏览器,当然,已经为Promise全局添加了polyfill

让我们看一下这个例子,看看下面的代码,了解TypeScript异步/等待表示法是如何工作的:

function delay(milliseconds: number, count: number): Promise<number> {return new Promise<number>(resolve => {setTimeout(() => {resolve(count);}, milliseconds);});
}// async function always returns a Promise
async function dramaticWelcome(): Promise<void> {console.log("Hello");for (let i = 0; i < 5; i++) {// await is converting Promise<number> into numberconst count:number = await delay(500, i);console.log(count);}console.log("World!");
}dramaticWelcome();

转换为ES6(--target es6)

var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {return new (P || (P = Promise))(function (resolve, reject) {function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }step((generator = generator.apply(thisArg, _arguments || [])).next());});
};
function delay(milliseconds, count) {return new Promise(resolve => {setTimeout(() => {resolve(count);}, milliseconds);});
}
// async function always returns a Promise
function dramaticWelcome() {return __awaiter(this, void 0, void 0, function* () {console.log("Hello");for (let i = 0; i < 5; i++) {// await is converting Promise<number> into numberconst count = yield delay(500, i);console.log(count);}console.log("World!");});
}
dramaticWelcome();

您可以在此处看到完整的示例。

转换为ES5(--target es5)

var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {return new (P || (P = Promise))(function (resolve, reject) {function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }step((generator = generator.apply(thisArg, _arguments || [])).next());});
};
var __generator = (this && this.__generator) || function (thisArg, body) {var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;function verb(n) { return function (v) { return step([n, v]); }; }function step(op) {if (f) throw new TypeError("Generator is already executing.");while (_) try {if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;if (y = 0, t) op = [0, t.value];switch (op[0]) {case 0: case 1: t = op; break;case 4: _.label++; return { value: op[1], done: false };case 5: _.label++; y = op[1]; op = [0]; continue;case 7: op = _.ops.pop(); _.trys.pop(); continue;default:if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }if (t[2]) _.ops.pop();_.trys.pop(); continue;}op = body.call(thisArg, _);} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };}
};
function delay(milliseconds, count) {return new Promise(function (resolve) {setTimeout(function () {resolve(count);}, milliseconds);});
}
// async function always returns a Promise
function dramaticWelcome() {return __awaiter(this, void 0, void 0, function () {var i, count;return __generator(this, function (_a) {switch (_a.label) {case 0:console.log("Hello");i = 0;_a.label = 1;case 1:if (!(i < 5)) return [3 /*break*/, 4];return [4 /*yield*/, delay(500, i)];case 2:count = _a.sent();console.log(count);_a.label = 3;case 3:i++;return [3 /*break*/, 1];case 4:console.log("World!");return [2 /*return*/];}});});
}
dramaticWelcome();

您可以在此处看到完整的示例。

注意:对于这两种目标方案,我们都需要确保我们的运行时在全球范围内都具有与ECMAScript兼容的Promise。这可能涉及为Promise争取一个polyfill。我们还需要通过将lib标志设置为“ dom”,“ es2015”或“ dom”,“ es2015.promise”,“ es5”之类的内容来确保TypeScript知道Promise的存在。 我们可以在此处查看哪些浏览器确实有Promise支持(本地和多填充)。

翻译来源:https://gitee.com/yunwisdoms/typescript-book/blob/master/docs/async-await.md

TyepScript入门教程 之 async await相关推荐

  1. 玩转异步 JS :async/await 简明教程(附视频下载)

    课程介绍 在软件开发领域,简洁的代码 => 容易阅读的代码 => 容易维护的代码,而 ES2017 中的 async/await 特性能让我们编写出相比回调地狱和 Promise 链式调用 ...

  2. python怎么输出浮点数_python 零基础入门教程第 2 章:基本数据类型 (一)

    一.什么是数据类型 编程语言通过一些复杂的计算机物理底层机制,创造不同类型的数据,用来表示现实世界中的不同信息,以便于计算机更好的存储和计算. 每种编程语言都会有一些基本的数据类型用来表示现实世界中的 ...

  3. Python基础入门教程:使用 Python 3 协程快速获得一个代理池

    Python基础入门教程:使用 Python 3 协程快速获得一个代理池 前言 在执行 IO 密集型任务的时候,程序会因为等待 IO 而阻塞.比如我们使用 requests 库来进行网络爬虫请求的话, ...

  4. 美团小程序框架mpvue入门教程

    美团小程序框架mpvue入门教程 自打写了 美团小程序框架mpvue蹲坑指南, 一发不可收拾,今天趁周末空闲,来写个mpvue(没朋友)的简单入门教程,本教程只针对新手,老鸟勿喷. 另外,我还专门为本 ...

  5. Nest入门教程 - 初识控制器

    Nest入门教程 - 初识控制器 控制器 控制器负责处理传入的 请求 和向客户端返回 响应 . 控制器的目的是接收应用的特定请求.路由机制控制哪个控制器接收哪些请求.通常,每个控制器有多个路由,不同的 ...

  6. OsharpNS轻量级.net core快速开发框架简明入门教程-基于Osharp实现自己的业务功能...

    OsharpNS轻量级.net core快速开发框架简明入门教程 教程目录 从零开始启动Osharp 1.1. 使用OsharpNS项目模板创建项目 1.2. 配置数据库连接串并启动项目 1.3. O ...

  7. JavaScript 的 async/await 理解(4)

    随着 Node 7 的发布,越来越多的人开始研究据说是异步编程终级解决方案的 async/await.我第一次看到这组关键字并不是在 JavaScript 语言里,而是在 c# 5.0 的语法中.C# ...

  8. vue 美团框架_美团小程序框架mpvue入门教程

    美团小程序框架mpvue入门教程 本教程只针对新手,老鸟勿喷. 另外,我还专门为本文做了一个简单的项目,如果懒得从头开始搭项目的童鞋,可以直接去我的 github上克隆到本地, 安装一下依赖,即可直接 ...

  9. Tauri 入门教程

    Tauri入门教程 1 简介 2 创建Tauri项目(页面基于Vue) 2.1 环境准备 2.2 创建工程 3 Tauri 工程目录介绍 4 页面调用rust方法 5 事件系统 6 HTTP请求 7 ...

最新文章

  1. SNMP OID批量枚举工具
  2. 算法 - 选择排序(C#)
  3. textarea怎么占满整个td_怎么知道网上的视频是不是专业摆拍?关注这些细节就可以了...
  4. 【实践】微博多尺度序列推荐算法实践.pdf(附下载链接)
  5. 【apue】UNIX环境高级编程 超详细介绍
  6. 传智播客杨中科老师的wpf基础视频教程、C#视频教程
  7. python knn模型_kNN模型(Python3.x环境)
  8. 2013年中国区Skyline软件价格体系
  9. 数据库基础介绍(1)几种常见的数据库
  10. python中并集的符号_Python 集合set添加删除、交集、并集、集合操作符号
  11. 压电式雨量传感器介绍说明
  12. 网站容器化升级---各模块分别运行一个容器
  13. 数据湖和数据仓库区别介绍
  14. VisualVM 使用心得
  15. 网页不收录的5大原因及解决办法
  16. 恶心的英特尔的RST驱动
  17. HackTheBox - Brainfuck Write Up
  18. 【mindspore】mindspore脚本迁移经历
  19. 欢迎观看Toni_hou的#生活5
  20. 洛阳计算机学校排名2015,洛阳初中名校排行榜TOP10,这一次你说了算!

热门文章

  1. XCode 4.2.1 项目的几个模版说明
  2. vim Ctrl+S锁定屏幕
  3. 查看容器ID以及如何在docker和宿主机之间复制文件
  4. LeetCode 344. Reverse String
  5. 【AI视野·今日Robot 机器人论文速览 第十三期】Wed, 23 Jun 2021
  6. 【AI视野·今日CV 计算机视觉论文速览 第152期】Fri, 9 Aug 2019
  7. 【今日CS 视觉论文速览】Fri, 21 Dec 2018
  8. 演练 制作爱奇异视频播放列表 0929
  9. 移动端相关 em rem px 区别和关联
  10. 2020-django目录