摘要:是异步编程的另一种解决方案函数是对函数的改进的基本用法函数函数返回一个实例,可以使用方法为返回的实例添加回调函数。函数内部语句返回的值,会成为方法回调函数的参数。也就是说,只有函数内部的异步操作执行完,才会执行方法指定的回调函数。
async await
async await是异步编程的另一种解决方案
async函数是对Generator函数的改进
async的基本用法 async函数async函数返回一个 Promise 实例,可以使用then方法(为返回的Promise实例)添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
例 1:
上面代码是一个获取股票报价的函数,函数前面的async关键字,表明该函数内部有异步操作。调用该函数时,会立即返回一个Promise实例。
async函数内部return语句返回的值,会成为then方法回调函数的参数。
Promise对象的状态变化async函数返回的 Promise对象,必须等到内部所有await命令后面的 Promise 对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。
await命令的基本用法正常情况下,await命令后面是一个Promise实例,如果不是,会被转成一个立即resolve的Promise实例。
async function f() { return await 123; } f().then(v => console.log(v))
等价于
async function f() { return await new Promise(function(resolve){ resolve(123) }) } f().then(v => console.log(v))
等价于
async function f() { return await Promise.resolve("123") } f().then(v => console.log(v))
await语句的返回值是await命令后面Promise实例的结果(异步处理的结果)
function getResult() { return new Promise((resolve) => { resolve("result: 1000") // resolve()方法的参数就是异步处理的结果 }); } async function asyncPrint() { const result = await getResult() // 将异步处理的结果赋值给result return result } asyncPrint().then( (result) => { console.log(result) } ) //"result: 1000"异常处理
如果await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject。
async function f() { await new Promise(function (resolve, reject) { throw new Error("出错了"); }); } f() .then(v => console.log(v)) .catch(e => console.log(e)) // Error:出错了
防止出错的方法,也是将其放在try...catch代码块之中。
async function f() { try { await new Promise(function (resolve, reject) { throw new Error("出错了"); }); } catch(e) { } return await("hello world"); }使用注意
如果await后面的异步操作出错,那么等同于async函数返回的 Promise 对象被reject,所以最好把await命令放在try...catch代码块中。
async function myFunction() { try { await somethingThatReturnsAPromise(); } catch (err) { console.log(err); } } // 另一种写法 async function myFunction() { await somethingThatReturnsAPromise() .catch(function (err) { console.log(err); }); }
多个await命令后面的异步操作,如果不存在继发关系,最好让它们同时触发。
let foo = await getFoo(); let bar = await getBar();
上面代码中,getFoo和getBar是两个独立的异步操作(即互不依赖),被写成继发关系(只有执行完getFoo操作,才能去执行getBar操作)。这样比较耗时,因为只有getFoo完成以后,才会执行getBar,完全可以让它们同时触发。
解释:这里的getFoo和getBar方法会返回两个Promise实例(假设是发起Ajax请求,请求foo和bar的内容),只有执行了方法,对应的操作才会执行,如果写成上面的形式,就会导致执行完getFoo的操作后(等待收到服务器的响应后),才能执行getBar的操作,这样就成了同步,比较耗时,因此可以将上面的写法修改,使得在等待getFoo执行完的时间内(在等待服务器响应的期间)去执行执行getBar
记住:当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
// 写法一 let [foo, bar] = await Promise.all([getFoo(), getBar()]); // 写法二 let fooPromise = getFoo(); let barPromise = getBar(); let foo = await fooPromise; let bar = await barPromise;
上面两种写法,getFoo和getBar都是同时触发,这样就会缩短程序的执行时间。
参考资料ECMAScript 6 入门
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/83786.html
摘要:异步操作成果异步操作失败方法可以接受两个回调函数作为参数。第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。等同于等同于这段代码会让这个对象立即进入状态,并将错误对象传递给指定的回调函数。 1.Promise的含义 Promise是异步编程的一种解决方案 Promise实例代表一个异步操作,从它可以获取异步操作的消息 Promise实例有三种状态: Pending...
摘要:匿名函数是我们喜欢的一个重要原因,也是,它们分别消除了很多代码细节上需要命名变量名或函数名的需要。这个匿名函数内,有更多的操作,根据的结果针对目录和文件做了不同处理,而且有递归。 能和微博上的 @响马 (fibjs作者)掰扯这个问题是我的荣幸。 事情缘起于知乎上的一个热贴,诸神都发表了意见: https://www.zhihu.com/questio... 这一篇不是要说明白什么是as...
摘要:整个事件循环是在一个线程里面的,意味着任务切换更加高效,无需上下文转换。异步代码很高效,但是也有很蛋疼的地方,那就是测试。所以我们得想办法告诉使用一个来运行测试方法。视频原文:Strategies for testing Async code - PyCon 2019 同时参考了: Testing Asyncio Python Code with Pytest 前面几篇关于异步编程的文章...
摘要:因为浏览器环境里是单线程的,所以异步编程在前端领域尤为重要。除此之外,它还有两个特性,使它可以作为异步编程的完整解决方案函数体内外的数据交换和错误处理机制。 showImg(https://segmentfault.com/img/bVz9Cy); 在我们日常编码中,需要异步的场景很多,比如读取文件内容、获取远程数据、发送数据到服务端等。因为浏览器环境里Javascript是单线程的,...
摘要:的翻译文档由的维护很多人说,阮老师已经有一本关于的书了入门,觉得看看这本书就足够了。前端的异步解决方案之和异步编程模式在前端开发过程中,显得越来越重要。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。 JavaScript Promise 迷你书(中文版) 超详细介绍promise的gitbook,看完再不会promise...... 本书的目的是以目前还在制定中的ECMASc...
阅读 1610·2021-09-02 15:11
阅读 1954·2019-08-30 14:04
阅读 2538·2019-08-27 10:52
阅读 1556·2019-08-26 11:52
阅读 1157·2019-08-23 15:26
阅读 2586·2019-08-23 15:09
阅读 2571·2019-08-23 12:07
阅读 2204·2019-08-22 18:41