体验异步的终极解决方案-ES7的Async/Await
阅读本文前,期待您对promise和ES6(ECMA2015)有所了解,会更容易理解。
本文以体验为主,不会深入说明,结尾有详细的文章引用。
第一个例子
Async/Await应该是目前最简单的异步方案了,首先来看个例子。
这里我们要实现一个暂停功能,输入N毫秒,则停顿N毫秒后才继续往下执行。
var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();
}, time);
})
};
var start = async function () {
// 在这里使用起来就像同步代码那样直观
console.log('start');
await sleep(3000);
console.log('end');
};
start();
控制台先输出start,稍等3秒后,输出了end。
基本规则
async 表示这是一个async函数,await只能用在这个函数里面。
await 表示在这里等待promise返回结果了,再继续执行。
await 后面跟着的应该是一个promise对象(当然,其他返回值也没关系,只是会立即执行,不过那样就没有意义了…)
获得返回值
await等待的虽然是promise对象,但不必写.then(..),直接可以得到返回值。
var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
// 返回 ‘ok’
resolve('ok');
}, time);
})
};
var start = async function () {
let result = await sleep(3000);
console.log(result); // 收到 ‘ok’
};
捕捉错误
既然.then(..)不用写了,那么.catch(..)也不用写,可以直接用标准的try catch语法捕捉错误。
var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
// 模拟出错了,返回 ‘error’
reject('error');
}, time);
})
};
var start = async function () {
try {
console.log('start');
await sleep(3000); // 这里得到了一个返回错误
// 所以以下代码不会被执行了
console.log('end');
} catch (err) {
console.log(err); // 这里捕捉到错误 `error`
}
};
循环多个await
await看起来就像是同步代码,所以可以理所当然的写在for循环里,不必担心以往需要闭包才能解决的问题。
..省略以上代码
var start = async function () {
for (var i = 1; i <= 10; i++) {
console.log(`当前是第${i}次等待..`);
await sleep(1000);
}
};
值得注意的是,await必须在async函数的上下文中的。
..省略以上代码 let 一到十 = [1,2,3,4,5,6,7,8,9,10]; // 错误示范
一到十.forEach(function (v) {
console.log(`当前是第${v}次等待..`);
await sleep(1000); // 错误!! await只能在async函数中运行
}); // 正确示范
for(var v of 一到十) {
console.log(`当前是第${v}次等待..`);
await sleep(1000); // 正确, for循环的上下文还在async函数中
}
第二个例子
这个例子是一个小应用,根据电影文件名,自动下载对应的海报。

直接贴出代码,就不说明了。
import fs from 'fs';
import path from 'path';
import request from 'request'; var movieDir = __dirname + '/movies',
exts = ['.mkv', '.avi', '.mp4', '.rm', '.rmvb', '.wmv']; // 读取文件列表
var readFiles = function () {
return new Promise(function (resolve, reject) {
fs.readdir(movieDir, function (err, files) {
resolve(files.filter((v) => exts.includes(path.parse(v).ext)));
});
});
}; // 获取海报
var getPoster = function (movieName) {
let url = `https://api.douban.com/v2/movie/search?q=${encodeURI(movieName)}`; return new Promise(function (resolve, reject) {
request({url: url, json: true}, function (error, response, body) {
if (error) return reject(error); resolve(body.subjects[0].images.large);
})
});
}; // 保存海报
var savePoster = function (movieName, url) {
request.get(url).pipe(fs.createWriteStream(path.join(movieDir, movieName + '.jpg')));
}; (async () => {
let files = await readFiles(); // await只能使用在原生语法
for (var file of files) {
let name = path.parse(file).name; console.log(`正在获取【${name}】的海报`);
savePoster(name, await getPoster(name));
} console.log('=== 获取海报完成 ===');
})();
其他信息
微软的Edge浏览器已经率先支持了async/await语法,相信不久之后chrome等浏览器、node.js也会跟进的,超期待!~(≧▽≦)/~
一些资料和工具
文中讲到的例子的源代码 https://github.com/think2011/ES7-Async-Await-Demo
方便的在线babel运行环境 https://babeljs.io/repl/
很详细的异步编程教程 http://es6.ruanyifeng.com/#docs/async
很详细的promise小书 http://liubin.github.io/promises-book/#introduction
体验异步的终极解决方案-ES7的Async/Await的更多相关文章
- ES7的Async/Await的简单理解
Async/Await 的个人见解 正文: async,顾名思义,一个异步执行的功能,而 await 则是配合 async 使用的另一个关键字,也是闻字识其意,就是叫你等待啦! 二者配合食用效果更佳哦 ...
- ES7 之 Async/await 的使用
在 js 异步请求数据时,通常,我们多采用回调函数的方式解决,但是,如果有多个回调函数嵌套时,代码显得很不优雅,维护成本也相应较高. ES6 提供的 Promise 方法和 ES7 提供的 Async ...
- ES7之async/await
async 是 ES7 才有的与异步操作有关的关键字. async 函数返回一个 Promise 对象,可以使用 then 方法添加回调函数. async function helloAsync(){ ...
- ES7的async/await
async 表示这是一个async函数,await只能用在这个函数里面. await 表示在这里等待promise返回结果了,再继续执行. await 后面跟着的应该是一个promise对象 awai ...
- 让webpack打包支持ES7的async/await语法
npm install --save-dev babel-plugin-transform-runtime npm install --save babel-runtime .babelrc配置 { ...
- js async await 终极异步解决方案
既然有了promise 为什么还要有async await ? 当然是promise 也不是完美的异步解决方案,而 async await 的写法看起来更加简单且容易理解. 回顾 Promise Pr ...
- [转] js async await 终极异步解决方案
阅读目录 回顾 Promise async await 字面理解 async.await 如何执行 await 操作符 总结 既然有了promise 为什么还要有async await ? 当然是pr ...
- 深入理解 JavaScript 异步系列(5)—— async await
第一部分,ES7 中引入 async-await 原文地址 http://www.cnblogs.com/wangfupeng1988/p/6532734.html 未经作者允许,不得转载~ 前面介绍 ...
- promise async await使用
1.Promise (名字含义:promise为承诺,表示其他手段无法改变) Promise 对象代表一个异步操作,其不受外界影响,有三种状态: Pending(进行中.未完成的) Resolved( ...
随机推荐
- Java笔记 #02# 带资源的try语句
索引 普通的 try.java 带资源的 try.java 当资源为 null 的情况 可以参考的文档与资料 / test.txt 待读取的内容 hello. / 普通的 try.java 读取 te ...
- Django框架介绍之一
这片博文就是对django有个大概的了解,通俗的说,就是先让django跑起来. django安装 在linux上安装如下: 源码安装: tar -zxvf Django-1.9.13.tar.gz ...
- Python3 打开 https 链接,异常:“SSL: CERTIFICATE_VERIFY_FAILED”
Python3 打开 https 链接,异常:“SSL: CERTIFICATE_VERIFY_FAILED” 一.问题 Python2.7.9 之后,当使用urllib.urlopen打开一个 ht ...
- 简单地说, cpp中的纯虚函数就是抽象类的具体实现
简单地说, cpp中的纯虚函数就是抽象类的具体实现.包含了纯虚函数的类就是抽象类.
- Arduino使用HC05蓝牙模块与手机连接
Arduino使用HC05蓝牙模块与手机连接 一切都是最好的选择 首先是线路连接,一定不要接错了 Arduino 代码 #include <SoftwareSerial.h> // Pin ...
- JavaScript 实现全选 / 反选功能
JavaScript 实现全选 / 反选功能 版权声明:未经授权,内容严禁转载! 构建主体界面 编写 HTML 代码 和 CSS 代码,设计主题界面 <style> #user { wid ...
- CEF解决加载慢问题
转载:http://blog.csdn.net/weolar/article/details/51994895 CEF加载慢的时候,加上以下代码,通过命令行的方式: CefRefPtr<CefC ...
- POJ 2785 4 Values whose Sum is 0 (二分)题解
思路: 如果用朴素的方法算O(n^4)超时,这里用折半二分.把数组分成两块,分别计算前后两个的和,然后枚举第一个再二分查找第二个中是否有满足和为0的数. 注意和有重复 #include<iost ...
- mybatis与hibernate常用的持久化类,及sqlsession和sqlsessionTemplate区别
首先, 通过翻阅源码,我们来整理一下mybatis进行持久化操作时重要的几个类:SqlSessionFactoryBuilder:build方法创建SqlSessionFactory实例.SqlSes ...
- C++课程上 有关“指针” 的小结
上完了C++的第二节课以后,觉得应该对这个内容进行一个小结,巩固知识点,并对我的心情进行了一个侧面烘托... 开始上课的老师: 正在上课的我: 上去敲代码的我: 过程是这样的: 下来的我: 非常的尴尬 ...