第126篇: 异步函数(async和await)

异步,函数,async,await · 浏览次数 : 128

小编点评

**输出结果:** ``` 1 2 3 4 I am bar 5 4 2 3 ``` **消息队列解释:** 1. `foo()` 调用异步函数 `foo()`。 2. `foo()` 中使用 `await` 关键字暂停 `Promise.resolve(8)` 的执行,等待 `Promise.resolve(8)` 的结果。 3. `foo()` 返回 `2`,并等待 `Promise.resolve(8)` 的结果。 4. `foo()` 返回 `3`,并等待 `Promise.resolve(8)` 的结果。 5. `foo()` 调用异步函数 `bar()`。 6. `bar()` 中使用 `await` 关键字暂停 `Promise.resolve(6)` 的执行,等待 `Promise.resolve(6)` 的结果。 7. `bar()` 返回 `4`,并等待 `Promise.resolve(6)` 的结果。 8. `bar()` 返回 `5`,并等待 `Promise.resolve(6)` 的结果。 9. `foo()` 的异步执行完成,并返回 `4`。 10. `foo()` 的结果(`4`)被添加到消息队列中。 11. `bar()` 的异步执行完成,并返回 `5`。 12. `bar()` 的结果(`5`)被添加到消息队列中。 **总结:** 该代码演示了如何使用 `async` 和 `await` 关键字来组织异步函数的执行。 `async` 关键字用于声明异步函数,并使用 `await` 关键字可以暂停函数的执行并等待结果。 `await` 关键字允许我们将异步函数与同步代码合并在一起,并将结果插入消息队列中。

正文

好家伙,本篇为《JS高级程序设计》第十章“期约与异步函数”学习笔记

 

ES8 的 async/await 旨在解决利用异步结构组织代码的问题。

为为此增加了两个新关键字:async 和 await。

 

1.async关键字

1.1.使用说明

async 关键字用于声明异步函数。

函数声明、函数表达式、箭头函数和方法都可以使用

使用 async 关键字可以让函数具有异步特征,但总体上其代码仍然是同步求值的。

而在参数或闭包方面,异步函数仍然具有普通 JavaScript 函数的正常行为。

async function foo() {} 
let bar = async function() {}; 
let baz = async () => {}; 
class Qux { 
 async qux() {} 
} 

 

 

1.2.返回值

异步函数如果使用 return 关键字返回了值(如果没有 return 则会返回 undefined),这个值会被 Promise.resolve()包装成一个期约对象。

异步函数始终返回期约对象。

async function foo() { 
    return 3; 
   } 
console.log(foo());

 

 

 也可以直接返回一个契约

async function bar() {
    console.log("I am bar");
    return Promise.resolve(3);
}
console.log("--------------");
console.log(bar());
console.log(1);

 

 

1.3.在异步函数中抛出错误会返回拒绝的期约

async function foo() { 
 console.log(1); 
 throw 3; 
} 
// 给返回的期约添加一个拒绝处理程序
foo().catch(console.log);
console.log(2); 

 

 

 

1.4.但是,拒绝期约的错误不会被异步函数捕获

async function foo() { 
 console.log(1); 
 Promise.reject(3); 
} 
// Attach a rejected handler to the returned promise 
foo().catch(console.log); 
console.log(2); 

 

 

 

 

2.await关键字

这里我们拆分一下 a-wait

也就是asynchronous-wait 异步-暂停

异步函数主要针对不会马上完成的任务,所以自然需要一种暂停和恢复执行的能力。

使用 await 关键字可以暂停异步函数代码的执行,等待期约解决。

(是暂停异步)

 

基本使用

async function foo() {
    let p = new Promise((resolve, reject) => setTimeout(resolve, 1000, 3));
    console.log(await p);
}
foo();
// 3 (一秒钟后出现) 

 

 

 

(然而这好像看不出什么)

 

要完全理解 await 关键字,必须知道它并非只是等待一个值可用那么简单。

JavaScript 运行时在碰 到 await 关键字时,会记录在哪里暂停执行。

等到 await 右边的值可用了,JavaScript 运行时会向消息 队列中推送一个任务,这个任务会恢复异步函数的执行。

 

async function foo(){
    console.log(1);
    console.log( await 4);
}
foo();
console.log(2);
console.log(3);

 

 

这里我们按上面的话尝试翻译一下发生了什么事

(1)调用异步函数foo()

(2)输出1

(3)准备打印,一看诶有个await,先暂停,为立即可用的值4向消息队列中添加一个任务,

( 怎么说呢,我反复看了很多遍.这里的意思大概是把一个要求值或者说要返回结果的式子推进消息队列,

但这里就只有一个4,求个毛线,直接就是4,就是把这个4推进消息队列. ),后让出线程

(4)执行同步函数输出 2

(5)输出3

(6)"4"求出来了,就是4

(7)await右边出值了,向消息队列中添加一个"恢复foo()执行"的任务

(8)从消息队列中取出"恢复foo()执行"的任务,恢复foo()异步函数的执行

(9)输出4

大概就是这么个过程

 

 

3.课后习题

 1.请给出下列代码的输出结果,并配合"消息队列"写出相关解释

 

async function foo() {
    console.log(2);
    console.log(await Promise.resolve(8));
    console.log(9);
}
async function bar() {

    console.log(4);
    console.log(await 6);
    console.log(7);
}
console.log(1);
foo();
console.log(3);
bar();
console.log(5);

 

尝试做一下吧,结果一定出乎你的意料

(明天再出一章写解释)

 

与第126篇: 异步函数(async和await)相似的内容:

第126篇: 异步函数(async和await)

好家伙,本篇为《JS高级程序设计》第十章“期约与异步函数”学习笔记 ES8 的 async/await 旨在解决利用异步结构组织代码的问题。 为为此增加了两个新关键字:async 和 await。 1.async关键字 1.1.使用说明 async 关键字用于声明异步函数。 函数声明、函数表达式、箭

第一百零五篇:变量的原始值和引用值

好家伙,JS基础接着学, 本篇内容为《JS高级程序设计》第四章学习笔记 1.原始值和引用值 ECMAScript变量可以包含两种不同类型的数据:原始值和引用值。原始值(primitive value)就是最简单的数据,引用值(reference value)则是由多个值构成的对象。 在把一个值赋给变

第一百零六篇:变量的不同声明(var,let和const的不同)

JS关于变量的声明,变量提升,暂时性死区

第一百零七篇:基本数据类型(undefined,null,boolean类型)

好家伙, 本篇内容为《JS高级程序设计》第三章学习笔记 1.数据类型 ECMAScript有6种简单数据类型(称为原始类型): Undefined, Null, Boolean, Number, String和Symbol。 Symbol (符号)是ECMAScript6新增的。还有一种复杂数据类型

第一百零八篇:最常用的基本数据类型(Number类型)

最常用的基本数据类型(Number类型)

第一百一十篇:内存泄漏和垃圾回收(JS)

好家伙,本篇内容为《JS高级程序设计》第四章的学习笔记 1.内存泄露 1.1.什么是内存泄漏? 内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。 内存泄漏缺陷具有隐蔽性、积累性的特征,比其

第一百一十一篇:基本引用类型Date

好家伙,本篇为《JS高级程序设计》第五章的学习笔记 1.基本引用类型 引用值(或者对象)是某个特定引用类型的实例,在ECMAScript中,引用类型是把数据和功能组织到一起的结构,(像极了“类”) 经常被人错误的称作“类”。 虽然从技术上讲JavaScript是一门面向对象语言,但是ECMAScri

第一百一十二篇: JS数组Array(一)数组基本用法

好家伙, 1.数组 Array应该就是ECMAScript中最常用的类型了。ECMAScript数组跟其他编程语言的数组有很大区别。 跟其他语言中的数组一样,ECMAScript 数组也是一组有序的数据, 但跟其他语言不同的是,数组中每个槽位可以存储任意类型的数据。 这意味着可以创建一个数组,它的第

第一百一十四篇: JS数组Array(三)数组常用方法

好家伙,本篇为《JS高级程序设计》第六章“集合引用类型”学习笔记 1.数组的复制和填充 批量复制方法 copyWithin(),以及填充数组方法fill()。 这两个方法的函数签名类似,都需要指定既有数组实例上的一个范围,包含开始索引,不包含结束索引。 使用这个方法不会改变数组的大小。 1.1.fi

第一百一十五篇: JS集合引用类型Map

好家伙,本篇为《JS高级程序设计》第六章“集合引用类型”学习笔记 1.Map ECMAScript6以前,在JavaScript中实现“键/值”式存储可以使用object来方便高效地完成,也就是使用对象属性作为键,再使用属性来引用值。 但这种实现并非没有问题,为此TC39委员会专门为“键/值”存储定