Рубрики
Без рубрики

Как преобразовать обратный вызов в асинхронный/ожидающий

У меня был какой-то код, который использовал обратный вызов. Не вдаваясь в подробности реализации, вот в чем суть: const uploadFile = (обратный вызов) = > { //загрузить файл, затем вызовите обратный вызов с указанием местоположения файла обратный вызов(местоположение) } загрузить файл((местоположение) = > {// продолжай}) Видишь? Я вызываю файл загрузки, и когда он заканчивает делать то, что ему нужно, он вызывает функцию обратного вызова. Но я использовал async/await во всех своих файлах, поэтому я решил использовать async/await и здесь, вместо использования обратного вызова.

У меня был какой-то код, который использовал обратный вызов. Не вдаваясь в подробности реализации, вот в чем суть:

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

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

Видишь? Я звоню загрузите файл и когда он закончит делать то, что ему нужно, он вызовет функцию обратного вызова.

Но я использовал async/await во всех своих файлах, поэтому я решил использовать async/await и здесь, вместо использования обратного вызова.

Вот как я это сделал: я завернул все тело функции uploadFile в вызов return new Обещание() , и когда я получил данные, которые хотел вернуть, я вызвал 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()

Теперь я мог бы использовать данные местоположение на первом уровне вместо того, чтобы включать их в функцию обратного вызова.

Это помогает мне поддерживать чистоту кода и лучше рассуждать об этом.

Если вам интересно, вот полный код фактической функции, чтобы вы могли увидеть эту концепцию в более крупном примере:

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`)
})

Оригинал: “https://flaviocopes.com/javascript-convert-callback-async-await/”