为什么有些方法前加了async,有些方法没有加async?

这是一个非常关键且常见的问题!在 JavaScript(包括 UniApp)中,是否使用 async 取决于函数内部是否需要使用 await 来处理异步操作。下面我们详细解释:


✅ 一、核心原则

只有当你在函数内部使用 await 时,才需要在函数前加 async

  • async 的作用是:让函数返回一个 Promise,并允许你在函数内部使用 await
  • 如果函数里没有 await,即使它调用了异步操作(比如 .then()),也不需要 async

✅ 二、结合你代码中的例子分析

🟢 加了 async 的方法(正确)

async loadData() {
  this.showSkeleton = true;
  try {
    const [bannersRes, activitiesRes] = await Promise.all([ // ← 使用了 await
      getBanners(),
      getActivities()
    ]);
    this.banners = bannersRes;
    this.activities = activitiesRes;
  } finally {
    this.showSkeleton = false;
  }
}

为什么加?
因为里面用了 await Promise.all(...),必须用 async 包裹才能使用 await


async loadGoodsList(isRefresh = false) {
  // ...
  try {
    const res = await getGoodsList({ ... }); // ← 使用了 await
    // ...
  }
}

为什么加?
因为调用了 await getGoodsList(...),这是一个异步 API 请求,需要用 await 等待结果。


🔴 没加 async 的方法(也正确)

onSearchClick() {
  const hotWords = getHotSearchWords(); // ← 这个函数虽然是 Promise,但没用 await
  uni.setStorageSync('HOT_SEARCH_WORDS', hotWords); // ← 同步操作
  uni.navigateTo({ url: '/pages/search/search' });
}

问题来了getHotSearchWords() 返回的是 Promise,但这里直接赋值给 hotWords,会导致 hotWords 是一个 Promise 对象,而不是数组!

👉 这是代码中的一个 Bug!应该修正为:

async onSearchClick() {
  const hotWords = await getHotSearchWords(); // ✅ 正确:用 await 获取真实数据
  uni.setStorageSync('HOT_SEARCH_WORDS', hotWords);
  uni.navigateTo({ url: '/pages/search/search' });
}

或者,如果你不想改函数,也可以不用 await,但要处理 Promise:

onSearchClick() {
  getHotSearchWords().then(hotWords => {
    uni.setStorageSync('HOT_SEARCH_WORDS', hotWords);
    uni.navigateTo({ url: '/pages/search/search' });
  });
}

所以:不是“有些方法不加 async”,而是“如果不用 await,就不需要 async”。但如果逻辑上需要等待异步结果,就必须用 async/await.then()


✅ 三、什么时候可以不加 async

情况 1:只触发异步操作,不关心结果

// 示例:点击按钮发送埋点日志,不需要等结果
logClick() {
  sendLog({ event: 'click_banner' }); // 假设这个函数返回 Promise,但我不等它
  // 继续执行其他同步逻辑
}

→ 不需要 async,因为没用 await

情况 2:使用 .then() 处理异步

loadData() {
  getBanners().then(banners => {
    this.banners = banners;
  });
}

→ 不需要 async,因为用的是 .then() 而不是 await


✅ 四、最佳实践建议

场景推荐写法
需要等待多个异步结果async + await(更清晰)
异步操作后需错误处理async + try/catch
只是触发异步,无需等待❌ 不加 async,直接调用
使用 .then() 链式调用❌ 不加 async

💡 现代开发中,优先使用 async/await 而不是 .then(),代码更易读、易维护。


✅ 五、总结

是否加 async关键判断依据
✅ 加函数内部使用了 await
❌ 不加函数内部没有 await(即使调用了异步函数)

⚠️ 注意:如果你调用了返回 Promise 的函数,但又需要它的结果,那么你必须await(此时要加 async)或 .then()(此时不加 async)。


🔧 修正建议

在你之前的代码中,onSearchClick 应该改为:

async onSearchClick() {
  const hotWords = await getHotSearchWords(); // ✅ 获取真实数组
  uni.setStorageSync('HOT_SEARCH_WORDS', hotWords);
  uni.navigateTo({ url: '/pages/search/search' });
}

否则 hotWords 是一个 Promise 对象,存到 storage 里会变成 [object Promise],导致搜索页热词显示异常。

Comments

No comments yet. Why don’t you start the discussion?

发表回复