热血病是什么病| 胆经不通吃什么中成药| k粉是什么| 阴历六月十三是什么日子| 达瓦里氏什么意思| 小腿痒痒越挠越痒是什么原因| 朱红色是什么颜色| 红颜什么意思| 血糖偏高能吃什么水果和食物最好| 梵高是什么画派| 六一年属什么生肖| 女生无缘无故头疼是什么原因| 什么的水果| 验大便能查出什么| 阴唇为什么一大一小| 经常吃紧急避孕药有什么危害| 液体套是什么| 脱氧核苷酸是什么| 小白鼠吃什么| 减肥期间吃什么主食| 不爱说话的人是什么性格| 什么是低碳生活| 跑马了是什么意思| 什么是碳足迹| 什么是牛黄| qeelin是什么牌子| 大姨妈能吃什么水果| 腰痛宁为什么晚上吃| 今天美国什么节日| 拖累是什么意思| 冠脉造影是什么意思| 神经官能症是什么| 万兽之王是什么动物| 世界上最难的数学题是什么| 众矢之的是什么意思| 贲门ca是什么意思| 桑葚酒有什么功效| 什么是速率| 质感是什么意思| 什么的叫| 脚围指的是什么| 精液发红是什么原因| 淳朴是什么意思| 偏旁部首是什么意思| m是什么码| 绿色和红色混合是什么颜色| 啤酒酵母是什么| 66什么意思| 一般细菌培养及鉴定是检查什么| 什么什么有力| o型血可以接受什么血型| 12点是什么时辰| 轴距是什么意思| 什么炒肉好吃| mj是什么意思| 为什么会流鼻血什么原因引起的| 诡异是什么意思| 大便蛋花状是什么原因| 赤日对什么| 骨密度增高是什么意思| prl是什么激素| 什么味道| 什么情况下吃丹参滴丸| 什么叫做光合作用| 肠梗阻是因为什么原因引起的| sp是什么的缩写| 属相鸡与什么属相相合| qid医学上是什么意思| 六味地黄丸是治什么病| 手串13颗代表什么意思| 微信为什么不能转账| 正常白带是什么样的| 人在囧途是什么意思| 翘首以盼什么意思| 老花眼视力模糊有什么办法解决吗| 1946年中国发生了什么| 同房什么意思| 什么是地包天牙齿| 引渡是什么意思| 太平果是什么水果| 妹汁是什么意思| 铁是什么元素| 喜欢吃酸的人是什么体质| 劣迹斑斑是什么意思| 经济危机是什么意思| 什么中药减肥| 头发全白是什么病| 为什么一热就头疼| 嗓子挂什么科| 牛肉与什么食物相克| 带状疱疹是什么引起的| 为什么记忆力很差| 令坦是对方什么人的尊称| 梦见刮胡子是什么意思| 火车上不能带什么| 胆囊粗糙是什么意思| 师傅和师父有什么区别| 狗狗不能吃什么| 茉莉什么时候开花| 子字五行属什么| 喝什么排湿气| 金牛男喜欢什么样的女生| 水牛背满月脸是什么病| 气短是什么症状| 珍珠五行属什么| 上面日下面立读什么| 宫颈筛查是检查什么| 亥时是什么时候| 赖是什么意思| 9.25什么星座| 股票解禁是什么意思| 负压引流器有什么作用| 东北冻梨是什么梨| 什么是肉刺图片大全| 胃肠外科是看什么病的| 黑脸代表什么| 菜花炒什么好吃| 洗牙有什么好处和坏处| 梦见别人拉屎是什么意思| 老人怕冷是什么原因| 为什么鞋子洗了还是臭| 沙僧头上戴的是什么| magnesium是什么意思| 荷花五行属什么| 每天放屁多是什么原因| 出家当和尚有什么要求| 大炮是什么| 荼什么意思| 澄面是什么面粉| 孕晚期头晕是什么原因| 脖子肿是什么原因| 吃什么降胆固醇最快| 闭经吃什么药| 吃桂圆干有什么好处和坏处| 怀孕初期胸部有什么变化| 视力5.3是什么概念| 嘬是什么意思| 酉是什么生肖| 坐月子能吃什么零食| 海带绿豆汤有什么功效| 蓝莓是什么季节的水果| 宫后积液是什么意思| 华妃娘娘是什么电视剧| 后会无期什么意思| 儿童嗓子疼吃什么药好| 情绪波动大是什么原因| 跳大神是什么意思| 12月25日是什么日子| 山五行属什么| 异丙醇是什么| 白虎痣是什么意思| 抑郁症是什么症状| 藜麦是什么东西| 洗面奶什么时候用最好| 儿童超敏c反应蛋白高说明什么| 一什么清香| 什么的舞动| 无限极是干什么的| 用维生素e擦脸有什么好处和坏处| 阿托伐他汀钙片什么时候吃最好| 睡前吃什么有助于睡眠| 喉结下面是什么部位| 早上起来嘴巴发苦是什么原因| 提前来大姨妈是什么原因| 邓超的老婆叫什么名字| 太字五行属什么| 祸水什么意思| pa是什么材质| 吃牛肉对身体有什么好处| 左心室强光点是什么意思| 肌酸激酶偏高说明什么| 满月送孩子什么礼物好| gst是什么意思| 新房送什么礼物好| 碳水化合物指的是什么| 颈部彩超能检查出什么| 什么叫梅核气| 人为什么要工作| 尿频尿急吃什么药效果最好| 包皮龟头炎用什么药| 青霉素v钾片治什么病| 粽子叶子是什么叶子| 多肽是什么| 翻盘是什么意思| 清谈是什么意思| 偏头痛什么原因| 支气管炎吃什么药| 肾钙化灶是什么意思| 精疲力尽是什么意思| 今年的属相是什么生肖| 眼皮有痣代表什么| 58年属什么| 属牛本命佛是什么佛| 走路脚心疼是什么原因| 什么高什么长| 1938年中国发生了什么| 相顾无言是什么意思| 牛肉和什么炒最好吃| 施华洛世奇水晶是什么材质| 角化型脚气用什么药最好| 国家三有保护动物是什么意思| 袍哥什么意思| 小号避孕套是什么尺寸| 蛇的天敌是什么动物| 心火大吃什么能清火| 红绿色盲是什么遗传病| 平安夜什么时候吃苹果| 松花蛋不能和什么一起吃| 无名指下面的竖线代表什么| 肚子突然变大是什么原因| 紫河车是什么东西| 温文尔雅是什么意思| 正痛片别名叫什么| 女性体寒 吃什么好| 屁股上长痘是什么原因| 吐司是什么| 气虚血瘀吃什么中成药| 消化内科是看什么病的| 止咳化痰吃什么药| 春什么秋什么的成语| 庙宇是什么意思| 农历六月十四是什么日子| 红红火火是什么生肖| 孟姜女属什么生肖| 散粉和粉饼有什么区别| 什么病不能吃豆制品| 玉米除草剂什么时候打最好| 1964年是什么年| 特别容易饿是什么原因| 5月是什么季节| 口苦是什么原因| 磷高有什么症状和危害| 畸胎瘤是什么病| 脑梗有什么症状前兆| 1943年属羊的是什么命| 宫颈纳囊是什么| 舌苔发白是什么症状| 投射效应是什么意思| 敞开心扉是什么意思| 腹泻吃什么好| 补办护照需要什么材料| 辱骂是什么意思| 老农民韩美丽结局是什么| 什么是肺炎| 70年属什么| 局气什么意思| 兔子的眼睛为什么是红色的| 什么水果对肝有好处| 意思是什么意思| 二尖瓣关闭不全是什么意思| 喉咙嘶哑是什么原因| 血脂高可以吃什么水果| 脑炎什么症状| 学士学位证书有什么用| 5s是什么| 桂枝茯苓丸主治什么病| hoho是什么意思| vintage什么意思| 真菌孢子是什么| 女人吃火龙果有什么好处| 猪油不凝固是什么原因| 体检吃早餐有什么影响| 血糖高适合吃什么水果| 眼霜有什么作用和功效| 百度

孩子咬指甲什么原因

原创
07/14 12:20
阅读数 5K
百度 轩朗的动力系统非常丰富,除了升和升两款自然吸气发动机外,还提供了一台发动机,与之匹配的是8挡手自一体自动变速器,可迸发出104千瓦的最大功率和234牛米的最大扭矩。

在 JavaScript 开发中,异步操作就像家常便饭 —— 从调用后端 API 到读取本地文件,几乎无处不在。但很多开发者都会困惑:到底该用 Promise 的链式调用,还是 async/await 语法?其实答案很简单:没有绝对的好坏,只有场景的适配

今天我们就用实际案例聊聊,这两种异步写法各自适合什么场景,以及如何在项目中混搭使用,让代码既高效又易读。

先搞懂:两者不是对立关系

很多人以为 async/await 是 Promise 的替代品,其实大错特错。async/await 本质是 Promise 的语法糖,它的底层依然是 Promise 实现。就像用for...of遍历数组比forEach更直观一样,async/await 让异步代码看起来更像同步代码。

先看个最简单的对比:

// Promise写法
fetchData().then(data => {
  return processData(data);
}).then(result => {
  console.log(result);
}).catch(err => {
  console.error(err);
});

// async/await写法
async function handleData() {
  try {
    const data = await fetchData();
    const result = await processData(data);
    console.log(result);
  } catch (err) {
    console.error(err);
  }
}

两者功能完全一致,但 async/await 的线性结构更符合人类的阅读习惯 —— 这也是它被广泛采用的核心原因。

优先用 async/await 的 3 种场景

什么时候用 async/await 更合适?记住一个原则:当异步操作需要按顺序执行,或者逻辑中有较多条件判断时

1. 线性异步流程(一步接一步)

最典型的场景是依赖前一步结果的异步操作。比如先登录获取 token,再用 token 获取用户信息,最后用用户信息加载权限配置:

// 用async/await,逻辑一目了然
async function initApp(username, password) {  // 补充参数定义,避免未定义变量
  try {
    const token = await login(username, password);
    const userInfo = await getUserInfo(token);  // 依赖token
    const permissions = await getPermissions(userInfo.role);  // 依赖userInfo
    renderApp(permissions);
  } catch (err) {
    showError(err);
  }
}

如果用 Promise 链式调用写,虽然能实现,但嵌套越深(比如再加两步),可读性会明显下降。

2. 包含条件判断的异步逻辑

当异步流程中需要根据结果做分支判断时,async/await 的优势更明显。比如:

async function checkAndUpdate() {
  const currentVersion = await getCurrentVersion();
  
  // 同步的条件判断,自然融入异步流程
  if (currentVersion < '2.0') {
    const updateInfo = await fetchUpdateInfo();
    if (updateInfo && updateInfo.force) {  // 增加可选链,避免updateInfo为undefined时报错
      await showForceUpdateDialog();
    } else {
      await showOptionalUpdateToast();
    }
  }
}

这段代码用 Promise 写会嵌套多层then,而 async/await 让同步逻辑和异步操作无缝衔接,就像写同步代码一样自然。

3. 需要中断执行的场景

有时候我们需要在异步流程中提前返回(比如参数无效时),async/await 的写法更直观:

async function submitForm(data) {
  // 同步校验
  if (!data?.email) {  // 增加可选链,避免data为null/undefined时报错
    showError('邮箱不能为空');
    return;  // 直接中断
  }
  
  // 异步操作
  try {
    const validateResult = await validateRemote(data);
    if (!validateResult.success) {
      showError(validateResult.message);
      return;  // 校验失败,中断
    }
    await submitData(data);
    showSuccess();
  } catch (err) {
    handleError(err);
  }
}

用 Promise 的话,需要在每个then里处理条件判断,代码会更零散。

优先用 Promise 的 3 种场景

虽然 async/await 很方便,但有些场景下,Promise 的原生 API(如Promise.allPromise.race)更适合,甚至不可替代。

1. 并行执行多个异步操作

当多个异步任务互不依赖时,用Promise.all并行执行能大幅提高效率。比如同时加载列表数据和筛选条件:

async function loadDashboard() {
  // 两个请求并行执行,总耗时是较慢那个的时间
  const [products, categories] = await Promise.all([
    fetchProducts(),
    fetchCategories()
  ]);
  
  renderProducts(products);
  renderFilters(categories);
}

如果用await逐个调用,会变成串行执行(总耗时是两者之和),完全没必要:

// 不推荐:串行执行,浪费时间
const products = await fetchProducts();
const categories = await fetchCategories();  // 等第一个完成才开始

2. 需要超时控制的异步操作

Promise.race可以实现 “谁先完成就用谁的结果”,非常适合超时控制。比如 “3 秒内没返回就显示加载失败”:

// 封装一个带超时的异步函数
function withTimeout(promise, timeoutMs = 3000) {
  let timer;  // 将timer提升到外部作用域
  const timeoutPromise = new Promise((_, reject) => {
    timer = setTimeout(() => {
      reject(new Error('请求超时'));
    }, timeoutMs);
  });
  return Promise.race([
    promise,
    timeoutPromise
  ]).finally(() => clearTimeout(timer));  // 确保始终清除定时器
}

// 使用
async function loadData() {
  try {
    const data = await withTimeout(fetchLargeData());
    render(data);
  } catch (err) {
    showError(err.message);  // 可能是超时错误
  }
}

这段代码用 async/await 无法实现,必须依赖 Promise 的race方法。

3. 处理动态数量的异步任务

当需要处理不确定数量的异步操作(比如批量上传多个文件),Promise.all是最佳选择:

async function uploadFiles(files) {
  if (!files?.length) return;  // 增加空值判断,避免空数组或undefined时执行无效操作
  
  // 生成一个包含所有上传Promise的数组
  const uploadPromises = files.map(file => {
    return uploadFile(file);  // 每个文件的上传是异步操作
  });
  
  // 等待所有文件上传完成
  const results = await Promise.all(uploadPromises);
  
  // 处理结果
  const successCount = results.filter(r => r?.success).length;  // 增加可选链容错
  showMessage(`成功上传 ${successCount}/${files.length} 个文件`);
}

这种动态场景下,Promise 的数组处理能力比 async/await 更高效。

混搭使用:发挥各自优势

实际开发中,两者往往结合使用效果最好。比如先并行获取基础数据,再串行处理后续逻辑:

async function buildReport() {
  // 第一步:并行获取不相关的数据(提高效率)
  const [users, orders, products] = await Promise.all([
    fetchUsers(),
    fetchOrders(),
    fetchProducts()
  ]);
  
  // 第二步:串行处理依赖关系的逻辑
  const userStats = await calculateUserStats(users);
  const orderSummary = await generateOrderSummary(orders, userStats);  // 依赖userStats
  const report = await compileReport(orderSummary, products);  // 依赖前两者
  
  return report;
}

这段代码先用Promise.all并行请求,节省时间;再用 async/await 处理有依赖的串行逻辑,兼顾效率和可读性。

避坑指南:这些错误别犯

  • 不要在循环中直接用 await

循环中用await会导致串行执行,如需并行,改用Promise.all

// 错误:串行执行,慢!
for (const file of files) {
  await uploadFile(file);
}
// 正确:并行执行,快!
await Promise.all(files.map(file => uploadFile(file)));
  • 别忘了 try/catch

async/await 中任何await的 Promise reject 都会触发异常,必须用try/catch捕获,否则会导致程序崩溃。

  • 不要把 async 函数当同步函数用

async 函数永远返回 Promise,调用时必须用await.then处理,直接调用会拿到 Promise 对象而非结果。

  • 避免过度封装

简单的异步操作(比如单个请求)没必要包成 async 函数,直接返回 Promise 更简洁。

  • 注意 Promise.all 的失败快速失败特性

Promise.all中任何一个 Promise reject 都会立即触发整个 Promise reject,如需等待所有结果(无论成功失败),可使用Promise.allSettled

// 等待所有任务完成,无论成功失败
// 文件上传场景优化
const results = await Promise.allSettled(uploadPromises);
const failedFiles = results
  .filter(r => r.status === 'rejected')
  .map((r, i) => ({ file: files[i].name, error: r.reason }));

总结:一句话记住用法

  • 用 async/await:处理线性依赖、包含条件判断、需要中断的异步流程;
  • 用 Promise API:处理并行任务(all)、超时控制(race)、动态异步数组;
  • 最佳实践:两者结合,并行任务用Promise.all,后续逻辑用 async/await 串联。

说到底,选择的核心是可读性和效率—— 哪种写法让团队成员更容易理解,哪种方式能让程序跑得更快,就用哪种。技术没有绝对的好坏,适合场景的才是最好的。

展开阅读全文
加载中
点击引领话题?? 发布并加入讨论??
0 评论
5 收藏
1
分享
返回顶部
顶部
什么是鸡眼 硬脂酸是什么 梦见自己穿孝衣有什么征兆 喝咖啡有什么好处 得了幽门螺旋杆菌有什么症状
3的倒数是什么 2.4什么星座 禹字五行属什么的 肺炎吃什么药效果好 多多保重是什么生肖
男人左手麻木什么原因 胰岛素抵抗吃什么药 无的放矢什么意思 4.25是什么星座 右耳烫代表什么预兆
山见念什么 超敏c反应蛋白高是什么意思 女人身体发热预示什么 体制内是什么意思 生肉是什么意思
血压低是什么情况hcv9jop7ns2r.cn 姨妈安全期是什么时候hcv7jop4ns8r.cn 小月子吃什么好hcv7jop5ns6r.cn 盆腔积液什么意思hcv8jop3ns3r.cn 干细胞有什么作用hcv9jop6ns2r.cn
赟怎么读 什么意思hcv9jop3ns8r.cn 眼睛疲劳用什么眼药水好hcv8jop1ns6r.cn y是什么元素hcv8jop4ns9r.cn 靶子是什么意思hcv9jop2ns4r.cn 全运会是什么hcv7jop6ns6r.cn
野生铁皮石斛什么价cj623037.com 月经不调吃什么药好hcv8jop0ns7r.cn 乌龟王八甲鱼鳖有什么区别hcv8jop7ns5r.cn 术语是什么意思hcv7jop9ns7r.cn 一什么一什么hcv7jop5ns0r.cn
瘦的快是什么原因bfb118.com 与狼共舞男装什么档次hcv9jop1ns2r.cn 什么是肺大泡hcv8jop3ns7r.cn 股骨头坏死什么症状bjcbxg.com 骨灰盒什么材质的好huizhijixie.com
百度