如何处理多个异步任务的依赖关系?

在真实项目中,异步任务之间往往存在复杂的依赖关系:有些任务可以并行,有些则必须等待另一些任务完成后才能开始。合理编排这些任务对于保证程序正确性和提升执行效率至关重要。

顺序依赖:一个接一个执行

当任务B依赖于任务A的结果时,我们必须确保A完成后才开始B。使用async/await是表达这种线性关系最清晰的方式。

async function sequentialDependent() {
  const user = await fetchUser(userId);
  const posts = await fetchUserPosts(user.id);
  const comments = await fetchPostComments(posts[0].id);
  return { user, posts, comments };
}

这段代码清晰地表明了数据流动的路径:user -> posts -> comments。每个await都会阻塞,直到其Promise解决,从而保证了严格的执行顺序。

并行无依赖:同时发起,等待全部

当多个任务间没有数据依赖,且都需要完成才能进行下一步时,应该让它们同时执行以节省时间。Promise.all()是处理这种场景的利器。

async function parallelIndependent() {
  const [userProfile, recentActivity, notifications] = await Promise.all([
    fetchUserProfile(),
    fetchRecentActivity(),
    fetchNotifications()
  ]);
  return { userProfile, recentActivity, notifications };
}

Promise.all接收一个Promise数组,并返回一个新的Promise。这个新Promise会在所有输入的Promise都成功解决后解决,并返回一个结果数组,其顺序与输入一致。任何一个输入Promise被拒绝,整个Promise.all会立即拒绝。

部分并行与复杂依赖

更常见的是混合场景:一组任务可以并行,但它们的共同结果又是下一组任务的前提。这需要组合使用上述两种模式。

async function complexDependencies() {
  // 第一步:并行获取基础数据
  const [catalog, userInfo] = await Promise.all([
    fetchProductCatalog(),
    fetchCurrentUser()
  ]);

  // 第二步:依赖第一步的结果,并行获取个性化数据
  const [recommendations, cart] = await Promise.all([
    fetchRecommendations(userInfo.id),
    fetchShoppingCart(userInfo.id)
  ]);

  // 第三步:依赖第二步的结果
  const estimatedDelivery = await calculateDelivery(cart.items);
  return { catalog, recommendations, cart, estimatedDelivery };
}

通过将独立的异步操作放在同一个Promise.all中,将有依赖的操作放在其后并用await等待前置结果,我们可以构建出高效的执行流程图。

动态依赖与条件执行

有时依赖关系在运行时才能确定。这时可以将异步任务封装成函数,并在条件满足时才加入执行队列。

async function dynamicDependencies(needsExtraData) {
  const basicData = await fetchBasicData();
  const tasks = [processBasicData(basicData)];

  if (needsExtraData) {
    tasks.push(fetchExtraData(basicData.id));
  }
  // 等待所有动态添加的任务完成
  const results = await Promise.all(tasks);
  return results;
}

Promise.allSettled()则在需要收集所有任务最终状态(无论成败)时非常有用。

在实际架构中,清晰的依赖关系管理是代码可维护性的关键。使用async/awaitPromise的组合,可以将复杂的异步工作流以近乎同步代码的可读性表达出来,同时兼顾执行效率。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

    暂无评论内容