Как написать цепочку обещаний с условием if в качестве первого оператора?

#javascript #node.js #promise

#javascript #node.js #обещание

Вопрос:

Обычно я бы сделал что-то вроде этого

   createQueue(sqs, queueName)
    .then(url => {
      return enqueue(sqs, url, message)
    })
    .then(messageId => {
      return res.status(HttpStatus.OK).send({ id: messageId })
    })
    .catch(err => {
      return handleErr(res, HttpStatus.INTERNAL_SERVER_ERROR, err)
    })
  

Но в этом случае у меня есть if проверка, существует ли URL, и если нет, я хочу вызвать createQueue , но в обоих случаях я хочу вызвать остальную часть цепочки обещаний.

Каков наилучший способ сделать это?

 // This doesn't work
if (!req.queueUrl) {
  return createQueue(sqs, queueName)
}
  .then(url => {
    const myUrl = req.queueUrl || url
    return enqueue(sqs, myUrl, message)
  })
  .then(messageId => {
    return res.status(HttpStatus.OK).send({ id: messageId })
  })
  .catch(err => {
    return handleErr(res, HttpStatus.INTERNAL_SERVER_ERROR, err)
  })
  

Обратите внимание, что именно так я решал эту проблему в прошлом

 const promises = []
if (!req.queueUrl) {
  promises.push(createQueue(sqs, queueName))
}
Promise.all(promises)
  .then(url => {
    const myUrl = req.queueUrl || url
    return enqueue(sqs, myUrl, message)
  })
  .then(messageId => {
    return res.status(HttpStatus.OK).send({ id: messageId })
  })
  .catch(err => {
    return handleErr(res, HttpStatus.INTERNAL_SERVER_ERROR, err)
  })
  

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

1. Что ожидает остальная часть цепочки, как url если вы имеете queueUrl ? Может быть (req.queueUrl ? Promise.resolve(req.queueUrl) : createQueue(sqs, queueName)).then(...); ?

2. хм, хороший вопрос. позвольте мне обновить.

3. Вы могли бы скрыть это условие внутри функции, которая либо возвращает createQueue(...) , либо Promise.resolve(req.queueUrl) . Или начните использовать async/await .

Ответ №1:

Цепочка фиктивных обещаний, которая разрешает URL, по которому вы можете переключить его на createQueue , если вам нужно. Я все еще не уверен, что вы подразумеваете под queueUrl против url.

 var startPromise = Promise.resolve(req.url);
if (!req.queueUrl) {
    startPromise = createQueue(sqs, queueName)
}
return startPromise.then(url => {
        return enqueue(sqs, url, message)
    })
    .then(messageId => {
        return res.status(HttpStatus.OK).send({
            id: messageId
        })
    })
    .catch(err => {
        return handleErr(res, HttpStatus.INTERNAL_SERVER_ERROR, err)
    })
  

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

1. req.queueUrl теперь установлено в промежуточном программном обеспечении. Я пытаюсь реорганизовать это, чтобы использовать это, если оно существует, в противном случае создайте очередь.

Ответ №2:

Аннотация с функцией для проверки и разрешения с помощью URL, если существует, или создания нового, если нет. Возвращайте getQueueURL , если требуется.

 function getQueueURL(queueURL) {
    if (!queueURL) {
        return createQueue(sqs, queueName);
    }

    return Promise.resolve(queueURL);
}

getQueueURL(req.queueUrl)
    .then(URL => enqueue(sqs, URL, message))
    .then(messageId => res.status(HttpStatus.OK).send({ id: messageId }))
    .catch(error => handleErr(res, HttpStatus.INTERNAL_SERVER_ERROR, error))