繁体   English   中英

等待不等待异步函数返回值

[英]await not waiting for async function to return value

我正在使用与 firebase 的反应,我需要将一些图片上传到 firebase 存储,然后保存从上传函数返回的下载 url 以将该值存储在 firestore 上。

这是我的图片上传功能

 const imageUpload = async (image) => { const uploadTask = storage.ref(`images/${image.name}`).put(image); uploadTask.on( 'state_changed', (snapshot) => {}, (error) => { console.log(error); }, () => { storage .ref('images') .child(image.name) .getDownloadURL() .then((url) => { setImageUrl(url); console.log(url); return url; }); } ); };

这是我的提交处理程序

 const handleSubmit = async (e) => { e.preventDefault(); let entry = { author: currentUser.email, body, }; if (image) { await imageUpload(image).then(async (url) => { console.log(url); entry = { author: currentUser.email, body, imageUrl, }; try { await createEntry(entry).then(() => { setBody(''); setShowSnackbar(true); }); } catch (error) { console.log(error); } }); } try { await createEntry(entry).then(() => { setBody(''); setShowSnackbar(true); }); } catch (error) { console.log(error); } };

但是,这不起作用,因为控制台首先显示未定义,然后显示 url,这意味着 await 不等待返回 url。 我如何解决这个问题?

问题主要是因为await然后一起使用。 通过将您的代码转换为使用 await only 可以提供帮助。

想象一下,一个地方的场景function c时,称为function a一个异步调用function b做出决议:

const a = () => {
     b().then(() => c());
};

这是相同的程序,使用 async/await 而不是 promise 编写:

const a = async () => {
    await b();
    c();
};

所以你的图片上传逻辑看起来像下面的代码,你可以转换其余的代码:

const url = await imageUpload(image)
console.log(url);
entry = {
  author: currentUser.email,
  body,
  imageUrl,
};

imageUpload 函数看起来像,

async function imageUpload(image) {
  try {
    const storageRef = firebase.storage().ref();
    // Create the file metadata
    const metadata = {     contentType: "image/jpeg" };
    const fileRef = storageRef.child(`${this.name}/` + image.name);
    const uploadTaskSnapshot = await fileRef.put(file, metadata);
    const downloadURL = await uploadTaskSnapshot.ref.getDownloadURL();
    setImageUrl(url);
    console.log(url);
    return downloadURL;
 } catch (error) {
    console.log("ERR ===", error);
 }
}

我认为你在混合东西。

如果您使用 async / await,则不需要在您的承诺中使用 then

使用 async/await 习惯用法,您的代码应该看起来更像

async function handleSubmit(e) {
  e.preventDefault();

  let entry = {
    author: currentUser.email,
    body,
  };

  if (image) {
    const url = await imageUpload(image);
    entry = {
      author: currentUser.email,
      body,
      imageUrl,
    };
    try {
      await createEntry(entry);
      setBody("");
      setShowSnackbar(true);
    } catch (error) {
      console.log(error);
    }
  }

  try {
    await createEntry(entry);
    setBody("");
    setShowSnackbar(true);
  } catch (error) {
    console.log(error);
  }
}

async function imageUpload(image) {
  const uploadTask = storage.ref(`images/${image.name}`).put(image);
  return new Promise((resolve, reject) => {
    uploadTask.on(
      "state_changed",
      (snapshot) => {},
      (error) => {
        reject(error);
      },
      () => {
        storage
          .ref("images")
          .child(image.name)
          .getDownloadURL()
          .then((url) => {
            setImageUrl(url);
            resolve(url);
          });
      }
    );
  });
}

async/await实际上是为了让带有 Promise 的编程以某种方式“感觉”同步。 使用 then 和回调,除了代码不起作用的事实之外,使它无法从语法中受益。

https://developer.mozilla.org/fr/docs/Learn/JavaScript/Asynchronous/Concepts

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM