本套笔记,是基于尚硅谷的课程整理

​Javascript(笔记51) - promise - 1 介绍与基本使用 ​

​Javascript(笔记52) - promise - 2 API和方法​

​Javascript(笔记53) - promise - 3 几个关键问题​

​Javascript(笔记54) - promise - 4 async函数、await表达式、结合示例​

补充:

​Javascript(笔记38) - ES6特性 - Promise​

​Javascript(笔记45) - ES8特性 - async 和 await​


async 函数

1)函数的返回值为 Promise 对象;

2)Promise 对象的结果由 Async 函数执行的返回值决定;

async function main() {

}
let result = main();
console.log(result); // promise

一个空的 async 函数,返回的也是 promise 对象,值是 undefined ,状态是成功; 

一般在谈 Promise 对象的结果,都是指两个东西:对象的状态 和 对象的值;

也就是说: result 是Promise对象,状态 PromiseState: fulfilled ; 值 PromiseResult: undefined; 


Async 函数执行的返回值一般有三种情况:Promise 对象、非Promise类型的数据和抛出异常

1)非Promise类型的数据:数值、字符串、布尔值等;

async function main() {
return 123;
// return "hello async";
// return true;
}
let result = main();
console.log(result); // promise 状态:成功

这种非Promise类型的数据,如:数字、字符串和布尔值等,直接决定 result 的状态是成功,函数返回值即为 result 的值;

2)Promise对象:返回值可以是 resolve(),也可以 reject(); 

async function main() {
return new Promise((resolve,reject)=>{
resolve('Ok');
// reject('Err');
});
}
let result = main();
console.log(result); // promise 状态:成功

返回的是 resolve() : result 的状态就为成功,值为 “Ok”; 

返回的是 reject():  result 的状态就是失败,值为 “Err”;

3)抛出异常:返回值是错误;

async function main() {
throw "oh No";
}
let result = main();
console.log(result); // promise 状态:失败; 值: oh No
result.catch(reason=>{ // 失败状态的Promise需要一个方法来处理失败,不然会报错
console.log(reason);// oh No;
});

返回值是错误,决定了 result 的状态是失败,这种失败的状态还需要一个方法来处理失败,如:catcth(),输出的失败值即为错误信息:oh No; 

Async 函数返回的 Promise对象的结果,跟 then() 方法返回 Promise对象的结果一样;

可以参考MDN:​​Async​


await 表达式

1) await 右侧的表达式一般为 promise 对象,但也可以是其它的值;

2)如果表达式是 Promise 对象,await 返回的是 promise 的值;

3)如果表达式是其他值,直接将此值作为 await 的返回值;

注意:

1)await 必须写在 async 函数中,但 async 函数中可以没有 await;

2)如果 await 的 Promise 失败了,就会抛出异常,需要通过 try...catch 捕获处理;

await 10;

语法错误:Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules.

await 必须写在 async 函数中;

第1种情况:右侧不是 promise对象,是一个其他类型的值,那 result 的值就是这个值;

async function main() {
// 1. 右侧不是 Promise 对象
let result = await 20;
console.log(result); // 20
}
main();

第2种情况:右侧是一个 promise对象(状态成功),那么 result 的值就是 Promise对象的值;

async function main(){    
let p = new Promise((resolve,reject)=>{
resolve('Ok');
});
// 2. 右侧是一个 promise 对象;
let result = await p;
console.log(result); // Ok
}
main();

第3种情况:右侧Promise对象状态是失败的话,那就要使用 try...catch 来捕获处理;

async function main() {
let p = new Promise((resolve, reject) => {
// resolve('Ok');
reject("Err");
});
try{
let result = await p;
console.log(result);
}catch(e){
console.log(e); // Err
}
}
main();

可以参考MDN:​​await​


结合示例1

在node环境,读取 res 文件夹中的三个文件: 1.md / 2.md / 3.md; 

回调写法:

const fs = require('fs');
fs.readFile('./res/1.md', (err, data1) => {
if (err) throw err;
fs.readFile('./res/2.md', (err, data2) => {
if (err) throw err;
fs.readFile('./res/3.md', (err, data3) => {
if (err) throw err;
console.log(data1 + data2 + data3);
});
});
});

Javascript(笔记54) - promise - 4 async函数、await表达式、结合示例_javascript

这种做法会形成回调地狱,不便维护;

async 和 await 写法:

const fs = require('fs');
const util = require('util');
const mineReadFile = util.promisify(fs.readFile); // 之前有介绍过 util.promisify 方法
async function main(){
try{
let data1 = await mineReadFile('./res/1.md');
let data2 = await mineReadFile('./res/2.md');
let data3 = await mineReadFile('./res/3.md');
console.log(data1+data2+data3);
}catch(e){
console.log(e);
}
};
main();

 这样看起来非常简洁,看起来像同步调用,其实内部执行是异步的;


结合示例2

async 与 await 结合发送 AJAX 

<button id="btn">点击获取图片</button>
<script>
// 之前封装的发送 ajax 的函数
function sendAjax(url) {
return new Promise((fulfill, reject) => {
const xhr = new XMLHttpRequest();
xhr.responseType = "json";
xhr.open("GET", url);
xhr.send(null);
// 处理结果,绑定事件
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
fulfill(xhr.response);
} else {
reject(xhr.status);
}
}
}
});
}

let btn = document.querySelector('#btn');
btn.addEventListener('click', async function () {
try {
let pics = await sendAjax('https://api.apiopen.top/api/getImages?page=0&size=10');
console.log(pics);
} catch (e) {
console.log(e);
}
});

</script>

调用公共接口的图片信息,点击按钮执行;

Javascript(笔记54) - promise - 4 async函数、await表达式、结合示例_async函数_02

注意:

sendAjax() 是之前封装的AJAX返回 promise 对象的函数;

await 必须放在 async 的函数里,所以 绑定回调函数中,要加上 async ;

使用 try...catch 来容错;