You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Redux项目Async/Await执行顺序异常:外部代码先于异步函数运行

问题整理

概述

我正在开发一个使用Redux的React应用,有一个action负责检查是否存在新的imageData,若存在则将其上传,获取返回的新URL后,使用该数据更新对象。

问题描述

异步函数内部的执行顺序符合预期,但函数外部的代码会在异步函数执行完成前就运行。

疑问

为什么底部的console log会在我写的异步函数内容全部执行完成前就触发?
相关代码:

if(imageData) {
      const imageGUID = guid();
      const storageRef = projectStorage.ref(`${imageData.name}_${imageGUID}`);
      // 该函数应当在底部的console log调用前执行完成
      await storageRef.put(imageData).on('state_changed', snap => {
        }, async (err) => {
          console.log(err)
          toastr.error("Uh Oh!", `Could not upload image`);
        }, async () => {
          imageURL = await storageRef.getDownloadURL();
          console.log("NEW IMAGE URL: ", imageURL);
          
      })
    }
    console.log("Done setting up new image: ", imageURL) // 该行代码在从Firestore获取IMAGE URL前就被调用,原因是什么?

解答

问题根因

storageRef.put(imageData).on() 方法返回的不是Promise对象,你在它前面加的await没有实际作用,代码不会等待回调逻辑执行完成就会往下走。
Firebase的on()是事件监听模式,你传入的第三个参数是上传完成后的成功回调函数,这个回调是异步触发的,不属于当前await能捕获的异步执行链,因此后续的console.log会先执行。

修复方案

将整个上传逻辑包装成标准Promise,手动控制resolve/reject的时机,这样await就能正常等待整个上传+获取URL的流程执行完成:

if(imageData) {
  const imageGUID = guid();
  const storageRef = projectStorage.ref(`${imageData.name}_${imageGUID}`);
  // 包装为Promise让await生效
  imageURL = await new Promise((resolve, reject) => {
    storageRef.put(imageData).on('state_changed', 
      snap => {}, 
      err => {
        console.log(err)
        toastr.error("Uh Oh!", `Could not upload image`);
        reject(err)
      }, 
      async () => {
        const url = await storageRef.getDownloadURL();
        console.log("NEW IMAGE URL: ", url);
        resolve(url)
      }
    )
  })
}
console.log("Done setting up new image: ", imageURL) 

修改后await会等待Promise内部的上传、获取URL全部执行完成后才会向下执行,底部的log就能拿到正确的imageURL了。


内容的提问来源于stack exchange,提问作者Bromox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 18:45:04