北京诚通新新建设有限公司网站wordpress edm
北京诚通新新建设有限公司网站,wordpress edm,wordpress 内容管理系统插件,中国新冠实际死了多少了1. Promise 是什么#xff1f;想象一下#xff0c;你去一家网红奶茶店买奶茶。因为人太多#xff0c;店员不能立刻做好。这时你有两个选择#xff1a;选择一#xff1a;一直等#xff08;同步思维#xff09;#xff1a;你就站在柜台前#xff0c;眼睛死死盯着制作区想象一下你去一家网红奶茶店买奶茶。因为人太多店员不能立刻做好。这时你有两个选择选择一一直等同步思维你就站在柜台前眼睛死死盯着制作区什么也不干直到奶茶做好。这期间你不能玩手机、不能和朋友聊天时间被完全浪费。这就是同步一件事做不完下一件就别想开始。选择二拿个小票异步思维店员给了你一张小票说“好了会叫你。” 现在你自由了你可以去玩手机、聊天等叫号了再过去取。这张小票就是Promise。Promise就是一张“未来会得到结果的承诺”小票。它有三种状态进行中你拿着小票等待中。这是 Promise 的初始状态。已成功店员喊你的号你成功拿到了一杯美味的奶茶。这个承诺兑现了。已失败店员过来说“不好意思您点的珍珠卖完了。” 这个承诺失败了。关键点一个 Promise 一旦从 pending 变为 fulfilled 或 rejected它的状态就永远确定了不能再改变。就像你拿到了奶茶成功或被告知卖完了失败这件事就结束了。2. Promise 怎么用—— .then() 和 .catch()我们拿到了“小票”Promise接下来该怎么处理结果呢Promise 提供了两个核心方法.then() 和 .catch()。.then()相当于你对店员说“如果成功了请给我加冰。”.catch()相当于你对店员说“如果失败了请帮我退钱。”代码示例假设我们有一个函数 buyMilkTea()它会立即返回一个“小票”Promise而不是奶茶本身。// 这个函数模拟买奶茶的过程2秒后返回结果 function buyMilkTea() { return new Promise((resolve, reject) { console.log( 店员开始制作奶茶...); setTimeout(() { if (Math.random() 0.2) { // 80% 的概率成功 resolve( 一杯美味的珍珠奶茶); // 兑现承诺 } else { // 20% 的概率失败 reject( 很抱歉珍珠卖完了); // 承诺失败 } }, 2000); // 模拟2秒的制作时间 }); } // 开始买奶茶 const milkTeaPromise buyMilkTea(); // 拿到小票后我们告诉店员成功和失败分别要怎么做 milkTeaPromise .then(milkTea { // 如果 resolve 被调用这里的代码就会执行 // milkTea 就是 resolve 传过来的值 console.log(成功拿到:, milkTea); console.log(开心地喝起来); }) .catch(error { // 如果 reject 被调用这里的代码就会执行 // error 就是 reject 传过来的值 console.log(出错了:, error); console.log(只好去买瓶水了。); });运行结果可能是 店员开始制作奶茶... (2秒后) 成功拿到: 一杯美味的珍珠奶茶 开心地喝起来也可能是 店员开始制作奶茶... (2秒后) 出错了: 很抱歉珍珠卖完了 只好去买瓶水了。这就是 Promise 的基本用法它让你能够优雅地处理一个未来才会知道结果的任务而不需要阻塞代码的执行。3. 为什么企业项目离不开 Promise在企业级开发中我们无时无刻不在处理异步操作例如发送 API 请求获取数据。读写浏览器本地存储。用户操作确认如“您确定要删除吗”的弹窗。Promise 是处理这些异步操作的“官方标准”它解决了传统回调函数带来的“回调地狱”问题。什么是回调地狱想象一下你要依次做三件事1. 登录获取用户ID - 2. 用ID获取用户详情 - 3. 用详情里的订单ID获取订单列表。如果用传统的回调函数代码会是这样login((loginRes) { getUserInfo(loginRes.userId, (userRes) { getOrderList(userRes.orderId, (orderRes) { console.log(订单列表:, orderRes); // 如果还有第四步、第五步...代码会不断向右缩进形成金字塔 }); }); });这种层层嵌套、难以阅读和维护的代码就是“回调地狱”。用 Promise 链式调用拯救它如果上面三个函数都返回 Promise代码会变得非常清晰login() .then(loginRes getUserInfo(loginRes.userId)) .then(userRes getOrderList(userRes.orderId)) .then(orderRes { console.log(订单列表:, orderRes); }) .catch(error { // 任何一步出错都会在这里被捕获 console.error(出错了:, error); });代码像一条平缓的河流从上到下流动逻辑清晰错误处理也集中在一处。这就是 Promise 在企业开发中的核心价值让异步代码的编写和阅读体验无限接近于同步代码。4. Promise 的写法new Promise(executor)Promise 的构造函数非常简洁它只接受一个参数const promise new Promise(executor);executor 是一个函数它会在 new Promise() 创建实例时被立即同步执行。这个函数本身又接收两个参数它们都是函数由 JavaScript 引擎提供我们称之为“回调函数”。const executor (resolve, reject) { // 异步操作的逻辑写在这里 // ... }; const promise new Promise(executor);第一个参数resolve 函数作用将 Promise 的状态从 pending进行中变为 fulfilled已成功。何时调用当你的异步操作成功完成时你应该调用 resolve。参数resolve 可以接收一个参数这个参数将成为 Promise 成功后传递给.then()回调函数的值。// 专业写法示例成功时调用 resolve function fetchUserData(userId) { return new Promise((resolve, reject) { console.log(开始获取用户数据...); // 模拟一个异步请求比如使用 fetch 或 axios setTimeout(() { // 假设我们成功从服务器获取到了数据 const userData { id: userId, name: 张三, role: admin }; // 调用 resolve并将数据作为参数传递出去 resolve(userData); // -- 关键点 }, 1000); }); } // 使用 fetchUserData(123).then(data { // 这里的 data 就是 resolve(userData) 传过来的值 console.log(成功获取到数据:, data); // { id: 123, name: 张三, role: admin } });专业技巧resolve 的参数可以是任何合法的 JavaScript 值包括另一个 Promise。如果传入的是另一个 Promise那么当前 Promise 的状态将完全由传入的 Promise 决定。第二个参数reject 函数作用将 Promise 的状态从 pending进行中变为 rejected已失败。何时调用当你的异步操作失败或遇到错误时你应该调用 reject。参数reject 通常接收一个参数这个参数会成为 Promise 失败的原因并传递给 .catch() 回调函数。强烈建议传递一个 Error 对象因为它能携带错误堆栈信息极大地方便调试。// 专业写法示例失败时调用 reject function fetchUserData(userId) { return new Promise((resolve, reject) { console.log(开始获取用户数据...); setTimeout(() { if (userId 100) { // 模拟一个错误用户不存在 // 专业做法创建一个 Error 对象 const error new Error(用户ID ${userId} 不存在); // 调用 reject并将错误对象作为参数传递出去 reject(error); // -- 关键点 } else { const userData { id: userId, name: 张三, role: admin }; resolve(userData); } }, 1000); }); } // 使用 fetchUserData(999) .then(data { console.log(成功获取到数据:, data); }) .catch(err { // 这里的 err 就是 reject(new Error(...)) 传过来的值 console.error(获取数据失败:, err.message); // 获取数据失败: 用户ID 999 不存在 console.error(错误堆栈:, err.stack); // 可以看到详细的错误调用栈 });为什么用 Error 对象如果你只传一个字符串 reject(用户不存在)在 .catch 里你只能拿到这个字符串。而用 new Error()你不仅能拿到 message还能拿到 stack错误堆栈这对于定位问题根源至关重要是企业级项目开发的规范。总结与最佳实践1. executor 的错误处理executor 函数内部如果发生同步错误比如 throw new Error()Promise 会自动捕获并将其状态变为 rejected效果等同于调用 reject。new Promise((resolve, reject) { // 下面这行代码会抛出错误 const data JSON.parse(这不是一个合法的JSON字符串); }).catch(err { console.log(err.message); // Unexpected token... });虽然Promise会自动捕获但为了代码的清晰和可控更推荐显式地使用try...catch包裹你的逻辑。function doSomethingRisky() { return new Promise((resolve, reject) { try { // 可能出错的同步代码 const result someRiskySyncOperation(); resolve(result); } catch (syncError) { // 同步错误直接 reject reject(syncError); } // 异步操作如回调、setTimeout的错误需要在回调内部处理 someAsyncOperation((err, asyncResult) { if (err) { // 异步错误也 reject reject(err); } else { resolve(asyncResult); } }); }); }2. 现代开发中其实很少直接 new Promise在企业项目中绝大多数时候不会亲手去写 new Promise(...)。因为现代 Web APIfetch、Service Worker 等原生 API 已经返回 Promise 对象。第三方库axios、request 等库的请求方法也返回 Promise。工具函数很多工具库已经将回调式的 API 封装成了 Promise。更多的时候是作为 Promise 的消费者使用.then(),.catch(),.async/await。那你什么时候需要自己写 new Promise当你需要将一个非 Promise 的异步操作通常是旧式的回调函数封装成 Promise 时。这被称为“Promise化”Promisification。经典案例封装 setTimeout// 封装一个延时函数 function delay(ms) { return new Promise(resolve { setTimeout(resolve, ms); // ms 毫秒后调用 resolve() }); } // 使用 console.log(开始); delay(2000).then(() { console.log(2秒后执行); // 2秒后打印 });经典案例封装一个回调式的文件读取 APINode.js 环境const fs require(fs); // 原始回调式 API // fs.readFile(file.txt, utf8, (err, data) { ... }); // Promise化封装 function readFilePromise(path, encoding) { return new Promise((resolve, reject) { fs.readFile(path, encoding, (err, data) { if (err) { // 如果有错误调用 reject reject(err); } else { // 如果成功调用 resolve resolve(data); } }); }); } // 使用 readFilePromise(./myfile.txt, utf8) .then(content { console.log(文件内容:, content); }) .catch(err { console.error(读取文件失败:, err); });5. 企业级项目中的 Promise 实战技巧在企业项目中我们不仅要会用 Promise更要用好它。技巧一统一封装 API 请求场景企业项目中所有API 请求都应该返回Promise这样上层业务逻辑才能使用.then()和.catch()。我们配置的 axios 拦截器其实就是在做这件事。axios.get() 或 axios.post() 本身返回的就是一个 Promise 对象。// src/api/user.js import request from /utils/request; // 这个 request 就是一个封装好的 axios 实例 // 这个函数返回一个 Promise export function getUserInfo(userId) { return request.get(/users/${userId}); } // 在组件中使用 getUserInfo(123) .then(data { this.userInfo data; }) .catch(error { this.$message.error(error.message); });技巧二使用 async/await 语法糖async/await是建立在Promise之上的语法糖它让我们能用写同步代码的方式来写异步代码是现代前端开发的标配。规则在一个函数前加上 async 关键字这个函数就变成了异步函数。在异步函数里可以用 await 关键字来“等待”一个 Promise 完成。await 只能在 async 函数内部使用。把上面的Promise 链式调用改写成async/await// 定义一个 async 函数 async function fetchOrderList() { try { // 用 await 等待 Promise 成功并把结果赋值给变量 const loginRes await login(); const userRes await getUserInfo(loginRes.userId); const orderRes await getOrderList(userRes.orderId); console.log(订单列表:, orderRes); } catch (error) { // 任何一步出错都会被 catch 捕获 console.error(出错了:, error); } } fetchOrderList();技巧三并发处理多个请求场景页面需要同时展示用户信息和用户权限这两个信息来自不同的 API 接口并且它们之间没有依赖关系。错误做法串行请求浪费时间。// 总耗时 时间A 时间B const userInfo await getUserInfo(); const userPermissions await getUserPermissions();正确做法使用Promise.all()并发请求。Promise.all() 接收一个 Promise 数组当所有 Promise 都成功时它才会成功并返回一个包含所有结果的数组。只要有一个失败它就立即失败。async function loadUserData() { try { // 同时发起两个请求总耗时 max(时间A, 时间B) const [userInfo, userPermissions] await Promise.all([ getUserInfo(), getUserPermissions() ]); console.log(用户信息:, userInfo); console.log(用户权限:, userPermissions); } catch (error) { console.error(加载用户数据失败:, error); } } loadUserData();这在企业项目中是提升页面加载性能的常用技巧。技巧四处理竞态条件场景用户快速点击一个按钮会连续发起多个相同的请求。我们只关心最后一次请求的结果之前的都应该被忽略。解决思路在发送新请求前取消掉上一个未完成的请求。这在axios中可以通过CancelToken或 AbortController实现通常也会封装在请求拦截器里。let pendingRequest null; async function fetchData(id) { // 如果上一个请求还在就取消它 if (pendingRequest) { pendingRequest.cancel(取消上一个请求); } // 创建新的取消令牌 const CancelToken axios.CancelToken; pendingRequest CancelToken.source(); try { const response await axios.get(/api/data/${id}, { cancelToken: pendingRequest.token }); console.log(response.data); pendingRequest null; // 请求完成后清除引用 } catch (error) { if (axios.isCancel(error)) { console.log(error.message); // 取消上一个请求 } else { console.error(请求失败:, error); } } }