查看: 222|回复: 0

ES6+异步编程:Promise与async/await错误处理

[复制链接]
发表于 2 小时前 | 显示全部楼层 |阅读模式
ES6+给JavaScript带来的变化集中在变量声明、函数写法、解构赋值、模块系统和异步组织方式。围绕箭头函数、Promise、async/await和错误处理,原文给出了一组可直接运行的示例。下面按代码实现、参数语义、错误原因和适用场景重新组织,便于在脚本开发和前后端联调中复用。

一、箭头函数、解构与参数处理
  1. const add = (a, b) => a + b;
  2. const square = x => x * x;
  3. const greet = ({ name, age }) => {
  4.   return `Hello ${name}, you are ${age} years old`;
  5. };
  6. const user = { name: 'Alice', age: 30, city: 'Beijing' };
  7. const { name, age } = user;
  8. const numbers = [1, 2, 3, 4, 5];
  9. const [first, second, ...rest] = numbers;
  10. const { city = 'Shanghai' } = user;
  11. function printUser({ name, age }) {
  12.   console.log(`${name}: ${age}`);
  13. }
复制代码
上述代码中,add和square利用箭头函数省略return;greet通过参数解构直接取得name和age;对象解构可配合默认值,数组解构用...rest收集剩余元素;printUser展示函数参数解构。落地时应注意:默认值只在对应属性为undefined时生效,const适合不需要重新赋值的配置和引用。

二、Promise链式调用与并发结果处理
  1. const fetchData = () => {
  2.   return new Promise((resolve, reject) => {
  3.     setTimeout(() => {
  4.       const data = { id: 1, name: 'test' };
  5.       resolve(data);
  6.     }, 1000);
  7.   });
  8. };
  9. fetchData()
  10.   .then(data => {
  11.     console.log('Data:', data);
  12.     return data.id;
  13.   })
  14.   .then(id => {
  15.     console.log('ID:', id);
  16.   })
  17.   .catch(error => {
  18.     console.error('Error:', error);
  19.   });
  20. const promise1 = fetchData();
  21. const promise2 = fetchData();
  22. Promise.all([promise1, promise2])
  23.   .then(results => {
  24.     console.log('All results:', results);
  25.   });
  26. Promise.allSettled([promise1, promise2])
  27.   .then(results => {
  28.     results.forEach(result => {
  29.       if (result.status === 'fulfilled') {
  30.         console.log('Success:', result.value);
  31.       } else {
  32.         console.log('Failed:', result.reason);
  33.       }
  34.     });
  35.   });
复制代码
fetchData用setTimeout在1秒后resolve一个对象,用于模拟异步数据。链式then中返回data.id后,下一个then才能拿到id;catch统一接收链上前面的异常。Promise.all等待全部成功,适合多个请求都成功才继续的场景。Promise.allSettled不会因为单项失败而丢失其他结果,遍历时按status区分fulfilled和rejected,分别读取value或reason。排查时先确认then中是否return了后续需要的数据,再检查catch是否被过早吞掉。

三、async/await与HTTP错误处理
  1. async function getUserData(userId) {
  2.   try {
  3.     const response = await fetch(`/api/users/${userId}`);
  4.     const user = await response.json();
  5.     const postsResponse = await fetch(`/api/users/${userId}/posts`);
  6.     const posts = await postsResponse.json();
  7.     return { ...user, posts };
  8.   } catch (error) {
  9.     console.error('Error:', error);
  10.     throw error;
  11.   }
  12. }
  13. async function processUsers() {
  14.   try {
  15.     const users = await Promise.all([
  16.       getUserData(1),
  17.       getUserData(2),
  18.       getUserData(3)
  19.     ]);
  20.     console.log('All users:', users);
  21.   } catch (error) {
  22.     console.error('Failed to get users:', error);
  23.   }
  24. }
  25. const fetchAndProcess = async () => {
  26.   const data = await fetchData();
  27.   return processData(data);
  28. };
  29. async function safeFetch(url) {
  30.   try {
  31.     const response = await fetch(url);
  32.     if (!response.ok) {
  33.       throw new Error(`HTTP error! status: ${response.status}`);
  34.     }
  35.     return await response.json();
  36.   } catch (error) {
  37.     console.error('Fetch failed:', error);
  38.     throw error;
  39.   }
  40. }
复制代码
getUserData按顺序await用户与文章请求;processUsers用Promise.all并发三个用户;async箭头函数保持与普通async函数一致的Promise返回特征。fetch请求在HTTP 4xx/5xx时不会自动进入catch,safeFetch用response.ok判断并抛出Error,这是原文错误处理代码的关键点。safeFetch先检查response.ok,非成功状态抛出带status的Error,再由catch打印并继续throw,调用方仍能感知失败。排查顺序建议:先看response.ok和status,再看catch中的error;并发场景看Promise.all外层catch;JSON解析失败也会进入catch。

四、对比与兼容性细节
异步模式对比:回调可读性低、错误处理困难、并发处理困难;Promise可读性中,错误处理用链式catch,并发用Promise.all;async/await可读性高,错误处理用try/catch,并发仍用Promise.all。变量声明对比:var是函数作用域、可重复声明、存在提升;let和const是块级作用域、不可重复声明、存在暂时性死区。模块系统对比:CommonJS静态分析否、树摇优化困难、浏览器需要打包;ES Modules静态分析是、树摇容易、浏览器原生支持。由此带来的工程影响是,ES Modules更利于静态分析和按需打包,但项目仍需结合浏览器兼容和构建流程;const优先可减少意外重赋值,需要变更引用时再用let。

五、代码风格与复用建议
const优先,箭头函数保持简洁,解构参数给出默认值。
  1. const PI = 3.14159;
  2. const config = { timeout: 5000 };
  3. const numbers = [1, 2, 3];
  4. const doubled = numbers.map(n => n * 2);
  5. function createUser({ name, email, age = 18 }) {
  6.   return { name, email, age };
  7. }
复制代码
这些写法与原文最佳实践一致:异步错误处理用try/catch或catch兜底,并发任务用Promise.all,若需要全部结果则用Promise.allSettled。原文总结中强调async/await是异步编程首选、const优先于let、ES Modules是趋势、Promise.all适合并发;在实际脚本中应结合错误边界和返回值的传递顺序使用。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-10-24 15:33 , Processed in 0.024968 second(s), 28 queries , Gzip On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部