TypeScript 简易教程一、TypeScript前导二、TypeScript基础语法三、TypeScript变量四、TypeScript Number+String类型五、TypeScript运算符六、TypeScript语句七、TypeScript函数八、TypeScript 容器类型九、TypeScript 接口、类、对象十、TypeScript 命名空间、模块、声明文件十一、Promise：JavaScript 异步编程的基石十二、TypeScript：Async Functions异步函数（Async Functions）是现代JavaScript编程中的一项重要特性，它使得处理异步操作变得更加简洁、直观。自从ES2017规范将其纳入标准以来，异步函数已经成为解决JavaScript中回调地狱（Callback Hell）问题、提高代码可读性和可维护性的利器。一、基本概念在JavaScript中，由于其单线程的执行环境，对于需要等待的操作（如网络请求、文件读写等I/O操作），传统的解决方案是使用回调函数或者Promise。然而，当这些异步操作嵌套过多时，代码会变得难以理解和维护，即所谓的“回调地狱”。异步函数正是为了解决这一问题而生，它允许你以同步的方式编写异步代码，使逻辑更加清晰。二、语法异步函数通过在函数声明前加上async关键字来定义，函数内部可以使用await关键字等待Promise的结果。下面是一个简单的异步函数示例：async function fetchUserData(userId) { try { const response = await fetch(`https://api.example.com/users/${userId}`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const userData = await response.json(); return userData; } catch (error) { console.error('Error fetching user data:', error); return null; } }三、工作原理async当一个函数被声明为async时，它总是返回一个Promise。这意味着你可以像处理其他Promise一样处理这个函数的返回值，即使函数内部没有显式地返回一个Promise。await在async函数内部，可以使用await关键字暂停函数的执行，直到等待的Promise解析完成。如果Promise成功（resolve），则await表达式的值就是Promise的解析值；如果Promise失败（reject），则会在当前函数中抛出异常，可以通过try...catch语句捕获。Promise每个异步函数都会隐式地返回一个Promise对象。即使你的函数没有明确返回任何值，它也会返回一个已解决（resolved）为undefined的Promise。如果你的函数用return语句返回了一个直接值，这个值会被封装进一个已解决的Promise。如果函数内部抛出了一个错误，则返回的Promise会被拒绝（rejected）并带有该错误。四、实际应用异步函数在处理各种异步操作时都非常有用，比如：当然，除了基础示例外，让我们进一步通过几个具体应用场景来加深对异步函数的理解和运用。文件读写操作（Node.js环境）在Node.js中，使用fs.promises模块进行异步文件操作非常适合与异步函数搭配使用。const fs = require('fs').promises; async function readAndWriteFiles() { try { // 异步读取文件 const content = await fs.readFile('source.txt', 'utf8'); console.log('读取到的内容:', content); // 异步写入新文件 await fs.writeFile('destination.txt', content, 'utf8'); console.log('文件写入成功'); } catch (err) { console.error('文件操作过程中发生错误:', err); } } readAndWriteFiles();并发处理多个异步操作异步函数结合Promise.all可以方便地并行执行多个异步操作，并在所有操作完成后得到结果。async function fetchDataParallel(userIds) { try { const promises = userIds.map(userId => fetchUserData(userId)); const users = await Promise.all(promises); console.log('所有用户数据:', users); } catch (error) { console.error('获取用户数据时出现错误:', error); } } // 假设我们有一个用户ID列表 const userIds = [1, 2, 3]; fetchDataParallel(userIds);延迟执行与定时任务异步函数可以和setTimeout结合，用于实现定时任务或延迟执行某些操作。async function delayedGreeting() { console.log('开始等待...'); await new Promise(resolve => setTimeout(resolve, 2000)); // 等待2秒 console.log('你好，世界！'); } delayedGreeting();错误处理与重试机制异步函数中，通过循环和条件判断可以简单实现错误处理和自动重试的逻辑。async function fetchWithRetry(url, retries = 3) { while (retries > 0) { try { const response = await fetch(url); if (response.ok) { const data = await response.json(); console.log('数据获取成功:', data); return data; } else { console.warn(`请求未成功，状态码：${response.status}，尝试重试...`); } } catch (error) { console.error('请求出错，准备重试:', error); } retries--; await new Promise(resolve => setTimeout(resolve, 1000)); // 每次尝试后等待1秒 } console.error('所有重试均失败'); return null; } fetchWithRetry('https://api.example.com/data');
TypeScript 简易教程一、TypeScript前导二、TypeScript基础语法三、TypeScript变量四、TypeScript Number+String类型五、TypeScript运算符六、TypeScript语句七、TypeScript函数八、TypeScript 容器类型九、TypeScript 接口、类、对象十、TypeScript 命名空间、模块、声明文件十一、Promise：JavaScript 异步编程的基石十二、TypeScript：Async FunctionsPromise是JavaScript中用于处理异步操作的一种编程模式，自ECMAScript 6（ES6）起成为语言标准的一部分。它提供了一种更为优雅和可控的方式来处理异步操作，相较于传统的回调函数，Promise能够更好地解决“回调地狱”问题，增强代码的可读性和可维护性。本文将详细介绍Promise的概念、基本用法、链式调用、静态方法以及在实际开发中的应用案例。一、Promise的基本概念Promise代表一个异步操作的最终完成（或失败）及其结果的容器。它有三种状态：Pending（等待中）：初始状态，既不是fulfilled也不是rejected。Fulfilled（已成功）：表示操作成功完成，此时Promise的值为resolve传递的值。Rejected（已失败）：表示操作失败，此时Promise的值为reject传递的原因。一旦Promise从Pending变为Fulfilled或Rejected，它的状态就不可更改了，这称为Promise的不可逆性。二、Promise的创建与使用Promise构造函数接受一个函数作为参数，该函数接收两个参数：resolve和reject，分别用于改变Promise的状态。const myPromise = new Promise((resolve, reject) => { setTimeout(() => { const success = true; if (success) { resolve("操作成功"); } else { reject("操作失败"); } }, 2000); });resolve和reject 作为参数传递给Promise构造函数中的执行器（executor）函数。resolve: 此函数用于将Promise的状态从pending（等待中）变为fulfilled（已成功）。当异步操作成功完成，或者你希望以某种成功的结果来解决Promise时，你应该调用resolve函数。resolve可以接受一个参数，这个参数将作为Promise的返回值传递给之后通过.then方法注册的回调函数。这个参数可以是任何类型的值，包括普通数据、对象，甚至是另一个Promise。reject: 此函数用于将Promise的状态从pending变为rejected（已失败）。当你希望以一个错误原因来拒绝Promise，表示异步操作未能成功完成时，应调用reject函数。同样地，reject也接受一个参数，该参数作为错误原因传递给之后通过.catch方法注册的错误处理回调函数。这个参数通常是一个错误对象，用于描述失败的具体原因。三、Promise的消费then方法.then()方法用于指定在Promise变为fulfilled状态时的回调函数，可以链式调用来处理多个后续操作。myPromise.then( value => console.log(value), // 当Promise成功时的处理 reason => console.error(reason) // 当Promise失败时的处理 );catch方法.catch()方法用于指定在Promise变为rejected状态时的回调函数，可以捕获前面链式调用中所有未被捕获的错误。myPromise.catch(error => console.error(error));四、Promise的链式调用通过.then()和.catch()可以实现Promise的链式调用，这样可以按顺序执行一系列异步操作，每个操作都依赖于前一个操作的成功或失败。myPromise .then(result => { console.log(result); return "下一个操作"; }) .then(nextResult => console.log(nextResult)) .catch(error => console.error(error));五、Promise的静态方法Promise提供了几个静态方法，用于处理多个Promise的情况：Promise.all()：等待所有的Promise都变为fulfilled状态，然后返回一个新的Promise，其结果是一个包含所有fulfilled状态的Promise结果的数组。如果有任何一个Promise变为rejected状态，则立即返回并拒绝，不等待其余的Promise。// 假设有三个异步操作，分别返回 Promise function fetchUser(userId) { return new Promise((resolve, reject) => { setTimeout(() => { console.log(`Fetching user ${userId}...`); // 模拟异步操作成功 resolve({ id: userId, name: `User ${userId}` }); // 如果想要模拟失败，可以使用 reject(new Error('Fetch failed')) }, 1000 * userId); }); } // 使用 Promise.all 同时发起三个异步请求 const userIds = [1, 2, 3]; const userPromises = userIds.map(userId => fetchUser(userId)); Promise.all(userPromises) .then(users => { console.log("所有用户数据已获取：", users); }) .catch(error => { console.error("其中一个请求失败：", error); }); Promise.race()：只要任意一个Promise变为fulfilled或rejected状态，就立即返回并结束，不等待其他Promise。function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(reject, ms, 'Timeout!'); }); } function requestWithTimeout(url, timeoutMs) { const requestPromise = fetch(url); const timeoutPromise = timeout(timeoutMs); return Promise.race([requestPromise, timeoutPromise]) .then(response => { if (response === 'Timeout!') { throw new Error('请求超时'); } return response.json(); // 假设 fetch 成功后我们想处理响应数据 }) .catch(error => { console.error('请求出错:', error.message); }); } // 假设我们有一个API请求，希望在5秒内完成，否则视为超时 requestWithTimeout('https://api.example.com/data', 5000) .then(data => console.log('获取到的数据:', data)) .catch(error => console.error('请求失败:', error)); Promise.resolve()：直接创建一个fulfilled状态的Promise。Promise.reject()：直接创建一个rejected状态的Promise。六、应用示例网络请求function fetchData(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open("GET", url); xhr.onload = () => { if (xhr.status === 200) { resolve(xhr.responseText); } else { reject(xhr.statusText); } }; xhr.onerror = () => reject(xhr.statusText); xhr.send(); }); } fetchData("https://api.example.com/data") .then(data => console.log(data)) .catch(error => console.error(error));