将回调函数转换为async/await的方法

570 阅读1分钟

我有一些使用回调的代码。没有太多的实现细节,这里是它的要点。

const uploadFile = (callback) => {
  //upload the file, then call the callback with the location of the file
  callback(location)
}

uploadFile((location) => {
  // go on
})

看到了吗?我调用uploadFile ,当它完成需要做的事情时,它就调用回调函数。

但是在我所有的文件中都使用了async/await,所以我决定在这里也使用async/await,而不是使用回调。

我是这样做的。我把uploadFile 函数的所有主体包裹在一个return new Promise() 调用中,当我得到我想要返回的数据时,我就调用resolve()

const uploadFile = () => {
  return new Promise((resolve, reject) => {
    //upload the file, then call the callback with the location of the file
    resolve(location)
  })
}

const location = await uploadFile()

现在我可以在第一层中使用location 的数据,而不是将其包裹在回调函数中。

这可以帮助我保持代码的清洁,并能更好地进行推理。

如果你有兴趣,这里有实际函数的完整代码,所以你可以在一个更大的例子中看到这个概念。

const uploadFile = (fileName, id, callback) => {
  const fileContent = fs.readFileSync(fileName)

  const params = {
    Bucket: process.env.AWS_BUCKET_NAME,
    Key: `file.jpg`,
    Body: fileContent
  }

  s3.upload(params, (err, data) => {
    if (err) {
      throw err
    }
    callback(data.Location)
  })
}

uploadFile(files.logo.path, job.id, async (location) => {
  await prisma.job.update({
    where: { id: job.id },
    data: {
      logo: location
    }
  })
})

下面是我把它转化成的内容。

const uploadFile = (fileName, id) => {
  return new Promise((resolve, reject) => {
    const fileContent = fs.readFileSync(fileName)

    const params = {
      Bucket: process.env.AWS_BUCKET_NAME,
      Key: `job-${id}.jpg`,
      Body: fileContent
    }

    s3.upload(params, (err, data) => {
      if (err) {
        reject(err)
      }
      resolve(data.Location)
    })
  })
}

handler.post(async (req, res) => {
  const files = req.files
  const body = req.body

  const job = await prisma.job.create({
    data: {
      ...body,
      created_at: new Date().toISOString()
    }
  })

  const location = await uploadFile(files.logo.path, job.id)

  await prisma.job.update({
    where: { id: job.id },
    data: {
      logo: location
    }
  })

  res.redirect(`/jobs/${job.id}/payment`)
})