Три полезных шаблона для более эффективного использования кода async/await в Javascript

1. Используйте функцию .catch вместо handleError

Нельзя передавать handleError напрямую в качестве второго параметра .then. handleError не улавливает ошибку, выданную process:

getPromise().then(process, handleError)

Что нужно сделать: передать handleError в .catch. .catch работает для ошибок, вызванных getPromise или process:

getPromise().then(process).catch(handleError)

2. Используйте finally для выполнения некоторого кода после того, как обещание выполнено или отклонено.

Нельзя вызывать один и тот же код в .then и .catch.

myPromise
.then(response => {
  doSomething(response)
  runFinalCode()
})
.catch(e => {
  returnError(e)
  runFinalCode()
})

Что нужно сделать: используйте наконец

myPromise
.then(response => {
  doSomething(response)
})
.catch(e => {
  returnError(e)
})
.finally(() => {
  runFinalCode()
})

3. Обертывание эфемерных ресурсов внутри асинхронной функции

Этот шаблон основан на предыдущем, чтобы обеспечить высвобождение ресурсов при разрешении или сбое функции.

const withTempDir = async (fn) => {
  const dir = await fs.mkdtemp(
    await fs.realpath(os.tmpdir()) + path.sep
  )
  try {
    return await fn(dir)
  } finally {
    fs.rmdir(dir, {recursive: true})
  }
}

await withTempDir((dir) => {
  // use dir to store temporary things
  // dir will always be delete when this function finishes or crashes
})