Как получить значение из обещания db.any () в pg-обещании? - PullRequest
0 голосов
/ 13 июля 2020
• 1000 обещание Promise { <pending> }, а не массив из json объектов, как я ожидал. Есть контроллер:
exports.getUsers = function (req, res) {
   let users = userModel.getAllUsers();
   console.log(users); // here it outputs Promise { <pending> }
   res.json(users);
 };

Как получить массив вместо обещания?

Ответы [ 2 ]

1 голос
/ 13 июля 2020

Если вы думаете, что код будет работать так, как вы его написали, я боюсь, вы не совсем поняли, что такое обещания, какие проблемы они решают и как работают.

Давайте разберем ваш код. Вы экспортируете функцию своего дизайна getUsers, которая должна возвращать последовательность пользовательских объектов. Но это не так - db.any(...) возвращает Promise. Как еще, по вашему мнению, можно вызвать then для возвращенного объекта? then является функцией-членом класса Promise , и вы передаете другую функцию then для работы с фактическими данными (переданными как параметр функции, которую вы передаете then). Это означает, что на самом деле data, переданное вызову then, вызванному возвращаемым значением вызова db.any(...), является последовательностью пользователей, которые вам нужны.

Ошибка, которую вы делаете, заключается в предположении что если вы return data из обратного вызова передали в then, оно станет возвращаемым значением вызова then(...). Это не будет . then всегда возвращает Promise - все, что вы вернете из обратного вызова в then, станет разрешенным значением возвращенного обещания, но это обещание, которое возвращается, и поэтому ваш Переменная users - это Promise.

Вам нужно больше узнать о обещаниях и о том, как они обрабатываются асинхронно ( между запуском ваших скриптов) и как синхронизировать ваш код при их разрешении.

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

Your getAllUsers функция может быть уменьшена до:

exports.getAllUsers = function () {
    return db.any("SELECT * FROM users;");
}

... а с await вы можете использовать ее как:

let users = await getUsers();

Вышеприведенный оператор должен быть частью функции, которая помечен как async, хотя для ECMAScript требуется marki ng явно, чтобы разрешить использование await выражений (и подразумевая, что вы не можете использовать await на верхнем уровне ваших скриптов):

async function whatever() {
    let users = await getUsers();
    /// ...
}

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

Для использования async и await требуется версия Node.js, которая может их поддерживать, но текущий выпуск поддерживает (на момент написания этой статьи).

В противном случае вы все равно можете сохранить функцию getUsers, но вам нужно использовать ее по-другому, поскольку вы не можете использовать await - необходимость использовать обещания, как это было до введения await и async, например:

getUsers().then(users => {
    /// Do something with the `users` array.
});

В любом случае, похоже, у вас есть некоторые дыры в понимании того, как работают обещания, и я рекомендую вам заполнить эти дыры, прочитав о них это время, а не просто переход к pg-promise API, который основан на них.

0 голосов
/ 13 июля 2020

Как вы уже выяснили, userModel.getAllUsers() вернет обещание, а не массив. Вам нужно подождать, пока это обещание будет выполнено. Это можно сделать с помощью async function.

exports.getUsers = async function (req, res) {
   let users = await userModel.getAllUsers();
   console.log(users);
   res.json(users);
};

Обратите внимание, что async function всегда будет возвращать обещание.

Или вы можете использовать метод then возвращенного обещания.

exports.getUsers = function (req, res) {
   userModel.getAllUsers().then(users => {
     console.log(users);
     res.json(users);
   });
};
...