Promise.resolve возвращает Undefined

Someone Special спросил: 28 марта 2018 в 02:49 в: javascript

Это продолжение Несколько обещаний - где разрешить? , где я использую один и тот же код для разных функций.

Однако это время Promise.resolve возвращается неопределенным.

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

1) Использование & & & в небулевой операции.

должен использовать

(console.log(results) , Promise.resolve(results)

вместо

console.log(results) && Promise.resolve(results)

2) Использование ненужного обещания .resolve - просто верните результаты из функции Async, чтобы получить тот же результат, что и с помощью Promise.resolve.

Мои конечные коды.

getMessages: function (roomId) {    return keysAsync('room:'+roomId)
    .then(room => 
        room === '' ? Promise.reject('Invalid room Id')
                    : smembersAsync('room:messages:'+roomId))
        .then(messagesId => { return messagesId })
        .catch(err => { return err }))}

Оригинальный вопрос Я использую nodejs promisify, поэтому у меня есть следующие объявления, объявленные как обещание для Redis

const { promisify } = require('util');
const getAsync = promisify(client.get).bind(client);
const hmsetAsync = promisify(client.hmset).bind(client);
const hsetAsync = promisify(client.hset).bind(client);
const incrAsync = promisify(client.incr).bind(client);
const smembersAsync = promisify(client.smembers).bind(client);
const keysAsync = promisify(client.keys).bind(client);
const sismemberAsync = promisify(client.sismember).bind(client);getMessages: function (roomId) {    return keysAsync('room:'+roomId)
    .then(room => 
        room === '' ? Promise.reject('Invalid room Id')
                    : smembersAsync('room:messages:'+roomId))
        .then(messagesId => console.log(messagesId) && Promise.resolve(messagesId))
        .catch(err => Promise.reject(err))},

И затем я вызываю функцию следующим образом

tools.getMessages('4').then((results) => {
    console.log('Messages in Room 4 => ', results);
  }).catch(err => console.log(err))

В моей консоли я вижу следующие результаты

['191', '192', '193', '194', '195', ' 196 ',' 197 ', "198", "199", "200", "201", "202", "207", "208", "209", "210", "211", '212', '213', '214', '215', '216', '217', '218'] // это когда я подключаю сообщения журнала Id

Сообщения в комнате 4 = > ; undefined // Это когда я результаты консольного журнала

3 ответа

Есть решение
Barmar ответил: 28 марта 2018 в 03:27

console.log() возвращает undefined, что неверно. && является оператором короткого замыкания и вычисляет второе выражение только тогда, когда первое выражение является истинным. Поэтому он никогда не выполняет Promise.resolve(messagesId).

Вместо && используйте оператор запятой. Он вычисляет оба выражения и возвращает второе.

    .then(messagesId => (console.log(messagesId), Promise.resolve(messagesId)))
jfriend00 ответил: 28 марта 2018 в 03:04
Или прекратите пытаться объединить несколько операторов в один и использовать фигурные скобки с двумя операторами (более читаемое решение IMO).
jfriend00 ответил: 28 марта 2018 в 03:06
И зачем вообще использовать Promise.resolve(). Это кажется ненужным.
T.J. Crowder ответил: 28 марта 2018 в 03:22
Я посмотрел на эту строку и увидел ||. || там не было, но это то, что я видел. Вздох.
Bergi ответил: 28 марта 2018 в 03:22
+1 для предложения оператора запятой, -1 для того, чтобы не использовать его в вашем примере кода. Вы не можете использовать оператор запятой в кратком теле стрелки - вы фактически вызываете then с двумя аргументами.
T.J. Crowder ответил: 28 марта 2018 в 03:23
И снова этот Promise.resolve ...
jfriend00 ответил: 29 марта 2018 в 03:13

Как уже было объяснено, вы получаете возвращаемое значение console.log(messagesId) в качестве вашего разрешенного значения, которое undefined из-за того, как работает && и что console.log() возвращает.

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

function log(arg) {
    console.log(arg);
    return arg;
}

Затем вы можете изменить это:

.then(messagesId => console.log(messagesId) && Promise.resolve(messagesId))

на это:

.then(log)

Обратите внимание, что в обработчике .then() любое возвращаемое вами простое значение станет разрешенным значением цепочки обещаний. Вы также можете вернуть обещание, если хотите добавить еще одну асинхронную операцию в цепочку обещаний, но если у вас уже есть значение, вы можете просто return value;. Вам не нужно return Promise.resolve(value);. Внутри обработчика .then(), Promise.resolve() просто лишний, ненужный код - просто возвращайте значение напрямую.

Luca ответил: 28 марта 2018 в 03:22

Обещание не разрешается с помощью messageId, так как console.log() возвращает undefined:

console.log(Boolean(console.log("test")));

Но это не единственное, что вы должны изменить, на самом деле, вы можете многое упустить, потому что функция smembersAsync() возвращает обещание, что вы можете просто вернуть:

вместо

return keysAsync('room:'+roomId)
    .then(room => 
        room === '' ? Promise.reject('Invalid room Id')
                    : smembersAsync('room:messages:'+roomId))
        .then(messagesId => console.log(messagesId) && Promise.resolve(messagesId))
        .catch(err => Promise.reject(err))

просто используйте

return keysAsync('room:'+roomId)
    .then(room => {
        if (room === "") { Promise.reject('Invalid room Id') } 
        else return smembersAsync('room:messages:'+roomId)
    })
jfriend00 ответил: 28 марта 2018 в 03:15
Здесь нет нерешенного обещания. Есть разрешенное значение, которое undefined.
Luca ответил: 28 марта 2018 в 03:18
Где неразрешенное обещание в моем коде? Я либо возвращаю a обещание, либо отклоняю его при данном условии
jfriend00 ответил: 28 марта 2018 в 03:19
Ваше первое предложение гласит: "Обещание никогда не будет решено". Это неверно
jfriend00 ответил: 28 марта 2018 в 03:21
Разрешается с разрешенным значением undefined. Это совершенно другая вещь, чем вообще не решаться.
Luca ответил: 28 марта 2018 в 03:20
Итак, что же происходит с этим обещанием?