У меня есть следующая функция, которая получает сообщение от aws SQS, проблема в том, что я получаю по одному за раз, и я хочу получить их все, потому что мне нужно проверять идентификатор для каждого сообщения:

function getSQSMessages() {

    const params = {
        QueueUrl: 'some url',
    };

    sqs.receiveMessage(params, (err, data) => {
        if(err) {
            console.log(err, err.stack)
            return(err);
        }
        return data.Messages;
    });

};

function sendMessagesBack() {

    return new Promise((resolve, reject) => {
        if(Array.isArray(getSQSMessages())) {
            resolve(getSQSMessages());
        } else {
            reject(getSQSMessages());
        };
    });

};

Функция sendMessagesBack () используется в другой функции async / await. Я не уверен, как получить все сообщения, так как я искал, как их получить, люди упоминают циклы, но я не мог понять, как реализовать это в моем случае. Я предполагаю, что мне нужно поместить sqs.receiveMessage () в цикл, но затем я запутываюсь в том, что мне нужно проверять и когда останавливать цикл, чтобы я мог получить идентификатор каждого сообщения?

Если у кого есть какие-либо советы, пожалуйста, поделитесь. Спасибо.

4
squeekyDave 1 Май 2019 в 12:54

3 ответа

Лучший ответ

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

Каждый запрос вернет «до» 10 сообщений, если вы не удалите их, есть вероятность, что следующий запрос для «до» 10 сообщений вернет набор сообщений, которые вы уже видели, и некоторые новые - так что ты никогда не узнаешь, когда увидишь их всех.

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

1
E.J. Brennan 1 Май 2019 в 13:14

Я предлагаю вам использовать API Promise, и это даст вам возможность использовать синтаксис async / await сразу.

const { Messages } = await sqs.receiveMessage(params).promise();
// Messages will contain all your needed info
await sqs.sendMessage(params).promise();

Таким образом, вам не нужно будет оборачивать API обратного вызова в Promises.

3
Alexandru Olaru 1 Май 2019 в 11:16

SQS не возвращает более 10 сообщений в ответе. Чтобы получить все доступные сообщения, вам нужно рекурсивно вызвать функцию getSQSMessages. Если вы возвращаете обещание от getSQSMessages, вы можете сделать что-то вроде этого.

getSQSMessages()
.then(data => {
  if(!data.Messages || data.Messages.length === 0){
      // no messages are available. return
  }
  // continue processing for each message or push the messages into array and call 
 //getSQSMessages function again. 
});
2
Swarup Bam 1 Май 2019 в 12:01