Преобразование обещания в асинхронную функцию

#javascript #promise #es6-promise

#javascript #обещание #es6-обещание

Вопрос:

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

 // working code
export const getUser = (req: Express.Request, res: Express.Response) =>
  new Promise((resolve, reject) => {
    passport.authenticate('oauth-bearer', { session: false }, (err, user) => {
      if (err) reject(err)
      if (user) resolve(user)
      else reject('Unauthorized')
    })(req, res)
  })
  

Это обещание используется с await ключевым словом:

 const user = await getUser(req, res)
  

Мои попытки до сих пор всегда возвращали «Функцию», а не разрешенное или отклоненное обещание:

 // failing code
export const getUser = (req: Express.Request, res: Express.Response) =>
  async () => {
      return await passport.authenticate('oauth-bearer', { session: false }, (err, user) => {
      if (err) throw err
      if (user) return user
      else throw 'Unauthorized'
    })(req, res)
  }
  

Спасибо, что указали, что я здесь делаю неправильно.

Комментарии:

1. Если passport.authenticate не возвращает обещание, значит, вы не можете. async функции — это синтаксический сахар, связанный с обещаниями; если обещания нет, вы не можете использовать этот синтаксис.

2. passport.authenticate действительно, это обычная функция. Но это вызывает обратный вызов. И я надеялся, что это можно было обернуть в async функцию. Поэтому мне не нужно использовать new Promise синтаксис.

3. Я не уверен, сработает ли это, но попробуйте await promisify(passport.authenticate)(… YOUR_PARAMS) и импортировать {promisify} = require(‘util’);

Ответ №1:

Вы получаете функцию вместо обещания, потому что new Promise создает обещание немедленно, но async () => {} создает обещание только при его вызове.

… но это наименьшая из ваших проблем.

async функции — это инструменты для управления существующими обещаниями. Они не могут быть свободно взаимозаменяемы с конструктором promise.

passport.authenticate не возвращает обещание, поэтому вы не можете использовать async для управления им.

Комментарии:

1. Спасибо, первое предложение о том, когда оно было создано, многое прояснило. Так что в некотором смысле это можно сделать, но тогда с помощью IIFE. Что делает его менее читаемым. Тогда придерживайтесь значений по умолчанию.

2. IIFE не помогло бы: вы все равно не смогли бы контролировать, будет ли обещание разрешено или отклонено функцией обратного вызова, которую вы передаете passport.authenticate

Ответ №2:

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

 export const getUser = async (req: Express.Request, res: Express.Response) => {
   return await functionThatReturnsAPromise()
}