Promise之async 与 await
一,async 函数
通过在函数声明前加上async关键字,可以将任何函数转换为返回Promise的异步函数。这意味着你可以使用.then()和.catch()来处理它们的结果。
<script> let result = async function myFn() { return 521 } //Proise的链式调用 result().then((res)=>{ console.log(res) // 521 },(reason)=>{ console.log(reason) }) </script>
⏰ async 修饰的函数返回一个非Promise对象时, 函数调用时产生的Promise对象的状态为‘fulfilled’, 结果值为返回的值
🌰示例
<script> let result = async function myFn() { //1. 如果返沪值是一个非Promise类型的数据 return 521 //result() 返回的Promise对象的结果值,取决这个值。result() 返回的Promise的对象的状态为‘fulfilled’ } console.log(result()); </script>
结果
⏰ async 修饰的函数返回一个Promise对象时,函数调用时产生的Promise对象的结果值和状态取决这个Promise对象
🌰示例一:成功
<script> let result = async function myFn() { //1. 如果返沪值是一个Promise类型的数据 return new Promise((resolve,reject)=>{ resolve('ok') //状态为成功,值为ok }) } console.log(result()); </script>
结果

🌰示例二:失败
<script> let result = async function myFn() { //1. 如果返沪值是一个Promise类型的数据 return new Promise((resolve, reject) => { reject('error') //状态为失败,值为error }) } console.log(result()); </script>
结果

🌰示例三:抛出异常
<script> let result = async function myFn() { //1. 如果返沪值是一个Promise类型的数据 return new Promise((resolve, reject) => { throw 'error' //状态为失败,只为‘error' }) } console.log(result()); </script>
结果
⏰ async 修饰的函数抛出异常时,函数调用时产生的Promise对象的状态为‘rejected’, 结果值为抛出异常的值
🌰示例
<script> let result = async function myFn() { throw '抛出异常' } console.log(result()); </script>
结果
🔉 总结:async 修饰的函数,调用时返回的Promise对象状态和结果值,给then方法很类似。
二,await 表达式
🔉 await 右侧的表达式一般为 promise 对象, 但也可以是其它的值。
注意:1. await 必须写在 async 函数中, 但 async 函数中可以没有 await。
2.
await关键字可以暂停async函数的执行,等待Promise的解决(resolve),然后以Promise的值继续执行函数。async function asyncFunction() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve("完成"), 1000) }); let result = await promise; // 等待,直到promise解决 (resolve) console.log(result); // "完成" } asyncFunction();3. 如果 await 的 promise 失败了, 就会抛出异常, 需要通过 try...catch 捕获处理。
⏰ 1. 如果表达式是 promise 对象, await 返回的是 promise 成功的值
🌰示例一:成功态
<script> let result = async function myFn() { //1.定义一个Promise 对象 let p = new Promise((resolve, reject) => { resolve('ok') }) //2.await使用 let res = p console.log(res); } result() </script>
结果

🌰示例二:失败态
<script> let result = async function myFn() { //1.定义一个Promise 对象 let p = new Promise((resolve, reject) => { reject('error') }) //2.await使用 //⚠️假如promise对象是失败的状态,需要try catch 才能获取错误值. try { let res = await p } catch (error) { console.log(error); } } result() </script>
结果

🌰示例三:抛出异常
<script> let result = async function myFn() { //1.定义一个Promise 对象 let p = new Promise((resolve, reject) => { throw '抛出异常' }) //2.await使用 //⚠️假如promise对象是失败的状态,需要try catch 才能获取错误值. try { let res = await p } catch (error) { console.log(error); } } result() </script>
结果

⏰ 2. 如果表达式是其它值, 直接将此值作为 await 的返回值
<script> let result = async function myFn() { //1.定义一个非Promise 对象 let x = 20 let y = 10 //2.await使用 let res = await (x + y) console.log(res) } result() </script>
结果
![]()
三,async 与 await 结合实践
🔉 async/await的目的是为了简化使用基于promise的API时所需的语法。
1. 基础用法
async函数返回一个Promise,而await关键词可以暂停async函数的执行,等待Promise解决。
async function myFn() { let p = new Promise((resolve, reject) => { setTimeout(() => { resolve('ok') }, 2000) }) let data = await p //等待,直到promise解决 (resolve) console.log(data) //完成 ‘ok’ }
2. 错误处理
使用try...catch结构处理async/await中的错误。
async function myFn() { let p = new Promise((resolve, reject) => { setTimeout(() => { // resolve('ok') reject('抛出异常') }) }) try { let result = await p console.log(result) //resolve 时 ‘ok’ } catch (error) { console.log(error) //reject 时 ‘抛出异常’ } }
3. 并行执行
Promise.all()可以用来并行执行多个await操作。
async function myFn(urls) { const promises = urls.map(url => fetch(url).then(r => r.json())); return await Promise.all(promises); }
4. 条件异步
根据条件执行await。
async function fetchData(condition) { if (condition) { return await fetch('url'); } return 'No fetch needed'; }
5. 循环中的await
在循环中使用await时,每次迭代都会等待。
async function sequentialStart(urls) { for (const url of urls) { const response = await fetch(url); console.log(await response.json()); } }
6. 异步迭代器
对于异步迭代器(例如Node.js中的Streams),可以使用for-await-of循环。
async function processStream(stream) { for await (const chunk of stream) { console.log(chunk); } }
7. await之后立即解构
直接在await表达式后使用解构。
async function getUser() { const { data: user } = await fetch('user-url').then(r => r.json()); return user; }
8. 使用默认参数避免无效的await
如果await可能是不必要的,可以使用默认参数避免等待。
async function fetchData(url = 'default-url') { const response = await fetch(url); return response.json(); }
9. await在类的方法中
在类的方法中使用async/await。
class DataFetcher { async getData() { const data = await fetch('url').then(r => r.json()); return data; } }
10. 立刻执行的async箭头函数
可以立即执行的async箭头函数。
(async () => { const data = await fetch('url').then(r => r.json()); console.log(data); })();
11. 使用async/await进行延时
利用async/await实现延时。
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function delayedLog(item) { await delay(1000); console.log(item); }
12. 使用async/await处理事件监听器
在事件处理函数中使用async/await。
document.getElementById('button').addEventListener('click', async (event) => { event.preventDefault(); const data = await fetch('url').then(r => r.json()); console.log(data); });
13. 以顺序方式处理数组
使用async/await以确定的顺序处理数组。
async function processArray(array) { for (const item of array) { await delayedLog(item); } console.log('Done!'); }
14. 组合async/await与destructuring以及spread运算符
结合使用async/await,解构和展开操作符。
async function getConfig() { const { data, ...rest } = await fetch('config-url').then(r => r.json()); return { config: data, ...rest }; }
15. 在对象方法中使用async/await
将async方法作为对象的属性。
const dataRetriever = { async fetchData() { return await fetch('url').then(r => r.json()); } };
16. 异步生成器函数
使用async生成器函数结合yield。
async function* asyncGenerator(array) { for (const item of array) { yield await processItem(item); } }
17. 使用顶级await
在模块顶层使用await(需要特定的JavaScript环境支持)。
// ECMAScript 2020引入顶级await特性, 部署时注意兼容性 const config = await fetch('config-url').then(r => r.json());
18. async/await与IIFE结合
将async函数与立即执行函数表达式(IIFE)结合。
(async function() { const data = await fetch('url').then(r => r.json()); console.log(data); })();
19. 使用async/await优化递归调用
async function asyncRecursiveFunction(items) { if (items.length === 0) return 'done'; const currentItem = items.shift(); await delay(1000); console.log(currentItem); return asyncRecursiveFunction(items); }
20. 在switch语句中使用await
在switch语句的每个case中使用await。
async function fetchDataBasedOnType(type) { switch (type) { case 'user': return await fetch('user-url').then(r => r.json()); case 'post': return await fetch('post-url').then(r => r.json()); default: throw new Error('Unknown type'); } }
四,async 与 await 结合发送 AJAX 请求
function sendAjax(url) { return new Promise((resolve,reject) => { const xhr = new XMLHttpRequest(); xhr.open('get',url); xhr.send(); xhr.onreadystatechange = function () { if(xhr.readyState === 4) { if(xhr.status>=200 && xhr.status < 300){ resolve(xhr.response); } else { reject(xhr.status); } } } }) } async function main() { let a = await sendAjax('https://api.apiopen.top/api/sentences'); console.log(a); } main();
浙公网安备 33010602011771号