await допустимо только в асинхронной функции - при использовании mongoosejs exec () - PullRequest
0 голосов
/ 24 мая 2018

Я портирую проект Hapi на v17 и сталкиваюсь с некоторыми проблемами с Mongoose при переходе на async / await.

С любым из моего кода, который использует 'await' на модели (mongoose), объектенапример:

const result = await User.findOne({email: email}).exec();

Я получаю следующее исключение при запуске 'node server.js'

            await User.findOne({}).exec();
        ^^^^^

SyntaxError: await is only valid in async function
at new Script (vm.js:74:7)
at createScript (vm.js:246:10)
at Object.runInThisContext (vm.js:298:10)
at Module._compile (internal/modules/cjs/loader.js:670:28)
at Object.Module._extensions..js 
(internal/modules/cjs/loader.js:713:10)
at Module.load (internal/modules/cjs/loader.js:612:32)
at tryModuleLoad (internal/modules/cjs/loader.js:551:12)
at Function.Module._load (internal/modules/cjs/loader.js:543:3)
at Module.require (internal/modules/cjs/loader.js:650:17)
at require (internal/modules/cjs/helpers.js:20:18)

Я использую узел v10.2.0 и mongoose 5.1.2 и не могу понять, почемуЯ получаю сообщение об ошибке.

В документации mongoosejs четко указано, что следует использовать exec () для возврата обещания при использовании async / await, как указано здесь

Любые предложения

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

await может использоваться только ВНУТРИ функции, которая объявлена ​​с ключевым словом async.

async function doSomething() {
    let result = await someMongoooseFunctionThatReturnsAPromise();
    // use result here
}

await не может использоваться вне функции async.Это то, что ваша ошибка говорит вам, и это никак не связано с мангустом.Это связано со структурой ВАШЕГО кода, который вызывает функцию mongoose.

ПРИМЕЧАНИЕ: Любой управляемый событиями код node.js УЖЕ находится внутри функции, поэтому для использования await вдля этой функции все, что вам нужно сделать, это добавить ключевое слово async к определению функции.Если вызывающая сторона этой функции не ожидает какого-либо возвращаемого результата, дальнейшие изменения не требуются.Если вызывающая сторона этой функции ожидает возвращаемого результата, вы должны адаптировать вызывающий код для ожидания возврата обещания из объявленной функции async.


Также стоит понять, чтоasync функция ВСЕГДА возвращает обещание.Хотя вы можете написать его как обычный последовательный код:

async function doSomething() {
    let result = await someMongoooseFunctionThatReturnsAPromise();
    // use result here
    result++;
    return result;
}

Эта функция фактически возвращает обещание, и разрешенное значение этого обещания будет возвращаемым значением функции.Поэтому, когда вы используете async функцию, подобную этой, вы должны использовать возвращаемое обещание:

 doSomething().then(finalResult => {
     console.log(finalResult);
 });

Итак, в вашем конкретном коде, если вы собираетесь использовать await, он должен быть внутри функции async:

async function someFunc() {
    const result = await User.findOne({email: email}).exec();
    // now this will work and you can use result here
}

В качестве альтернативы вы можете использовать .then() вместо:

User.findOne({email: email}).exec().then(result => {
    // process result here
    // continue with other code that uses result here
});

ПРИМЕЧАНИЕ. Для обработки ошибок при использованииasync/await, у вас есть два варианта:

  1. Вы можете использовать традиционные try/catch внутри любой объявленной функции async, и try/catch будет перехватывать любые отклоненные обещания с await.

  2. Если вы не используете try / catch и await внутри вашей функции отклоняет, то обещание, которое возвращает сама функция, будет отклонено, и вызывающая сторона вашей функции получитотклоненное обещание.

Итак, все зависит от ситуации.Если вы хотите обрабатывать отклонение локально, то вы должны использовать try / catch около await (так же, как если бы вы .catch(). Если вы хотите, чтобы отклонение всплывало до вызывающего абонента, чтобы они увидели отклоненное обещание, тогдавам не нужен try/catch, поскольку интерпретатор Javascript автоматически выдаст отклоненный await, отклонив обещание, которое возвращает функция async.

0 голосов
/ 25 мая 2018

Вам необходимо заключить код в асинхронную функцию, подобную этой

async function fetchFun() {
  const result = await User.findOne({email: email}).exec();

  console.log('Results fetched!'); //etc
}

fetchFun(); // <--

Примечание: Вам все равно придется вызывать эту функцию без await, как я указал стрелкой, потому чтодолжен быть некоторый вход в ваш код асинхронного / ожидающего кода (например, main() в C), и эту функцию входа нельзя вызвать с помощью await

...