Me han dicho que "await solo es válido en una función asíncrona", a pesar de que está en una función asíncrona. Aquí está mi código:

async function uploadMultipleFiles (storageFilePaths,packFilePaths,packRoot) {
    return new Promise((resolve,reject) => {
        try {
            for (i in storageFilePaths) {
                await uploadFile(storageFilePaths[i],packFilePaths[i],packRoot) // error throws on this line
            }
            resolve("files uploaded")
        } catch {
            console.log(err)
            reject("fail")
        }
    })
}

¿Por qué sucede esto cuando lo convertí en una función asíncrona? ¿Es porque estoy usando un bucle for? Si es así, ¿cómo puedo obtener el resultado esperado sin este error?

1
pufferfish 25 ago. 2020 a las 13:43

3 respuestas

La mejor respuesta

La función que define a partir de la línea 1 es async.

La función de flecha que define en la línea 2 y pasa al constructor de Promise no es asincrónica.


También está utilizando el antipatrón de promesa múltiple . Deshazte del constructor Promise por completo. Simplemente devuelva el valor cuando lo tenga. Ese es uno de los principales beneficios de la palabra clave async.

async function uploadMultipleFiles(storageFilePaths, packFilePaths, packRoot) {
    try {
        for (i in storageFilePaths) {
            await uploadFile(storageFilePaths[i], packFilePaths[i], packRoot) // error throws on this line
        }
        return "files uploaded";
    } catch {
        console.log(err);
        throw "fail";
    }
}
5
Quentin 25 ago. 2020 a las 10:45

Solo puede usar await dentro de una función async , el error se refiere a la devolución de llamada que está pasando a su nuevo {{X2 }} (ya que está ingresando un nuevo alcance de función allí).

async function uploadMultipleFiles (storageFilePaths,packFilePaths,packRoot) {
  return new Promise((resolve,reject) => { // <========= this arrow function is not async 
      try {                                // so you cant use await inside
          for (i in storageFilePaths) {
              await uploadFile(storageFilePaths[i],packFilePaths[i],packRoot) // error throws on this line
          }
          resolve("files uploaded")
      } catch {
          console.log(err)
          reject("fail")
      }
  })
}

La parte en la que intentas construir un nuevo Promise es en realidad redundante ya que una función async se resolverá en un Promise de todos modos (leer más aquí ). Entonces podrías escribir tu código de la siguiente manera:

async function uploadMultipleFiles (storageFilePaths,packFilePaths,packRoot) {
  try {
      for (i in storageFilePaths) {
          await uploadFile(storageFilePaths[i],packFilePaths[i],packRoot) // error throws on this line
      }
      return "files uploaded"
  } catch {
      console.log(err)
      throw new Error("fail");
  }
}
2
etarhan 25 ago. 2020 a las 12:14

La devolución de llamada Promise no es asincrónica

async function uploadMultipleFiles (storageFilePaths,packFilePaths,packRoot) {
    return new Promise(async (resolve,reject) => {
        try {
            for (i in storageFilePaths) {
                await uploadFile(storageFilePaths[i],packFilePaths[i],packRoot) // error throws on this line
            }
            resolve("files uploaded")
        } catch {
            console.log(err)
            reject("fail")
        }
    })
}
-2
Daniel 25 ago. 2020 a las 10:47