Условно отправляйте ответы в приложении Express - PullRequest
1 голос
/ 27 июня 2019

Мне интересно, можете ли вы написать if операторы в приложении Express для условного выполнения вашего кода без предоставления else операторов.

if(pred) {
  doSomething()
}
return foo;
calcBar(); // doesn't run.

Выше приведен синхронный код, который останавливает выполнение послеreturn оператор.

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

app.get('/matches', async function(req, res) {
  try {
    const data = await someGraphQLCall();
    if(data.length === 0) {
      res.json({ message: "No data." });
    }
    const someOtherData = await someOtherGraphQLCall(data.foo);
    res.json({ someOtherData });
  } catch (err) {
    res.json({err})
  }
}

Я знаю из-за этого вопроса , что код после первого res.json все еще может бытьказнены.Есть ли способ остановить это?Я не хочу, чтобы второй вызов GraphQL выполнялся, если выполняется первый, если выполняется условие.Это возможно без использования else?

Редактировать:

Поскольку вопрос, который я упомянул выше, использование оператора return является плохим вариантом, потому что:

также делает его менее значимым и расплывчатым, поскольку использует неверную семантику.Если вы не используете значение из функции, вы не должны возвращать его.

Ответы [ 3 ]

3 голосов
/ 27 июня 2019

Вы можете использовать ключевое слово return в первом ответе, чтобы немедленно вернуться из функции.

app.get('/matches', async function(req, res) {
  try {
    const data = await someGraphQLCall();
    if(data.length === 0) {
      return res.json({ message: "No data." });
    }
    const someOtherData = await someOtherGraphQLCall(data.foo);
    res.json({ someOtherData });
  } catch (err) {
    res.json({err})
  }
} 

Edit:

В качестве альтернативы вы можете разделить логику данных и создать ответ. Таким образом, вы можете использовать возврат, и его легче читать:

app.get('/matches', async function (req, res) {
    try {
        const data = await getDataFromGraphQLCall();
        res.json(data);
    } catch (err) {
        res.json({ err })
    }
});

async function getDataFromGraphQLCall() {
    const data = await someGraphQLCall();
    if (data.length === 0) {
        return { message: "No data." };
    }
    const someOtherData = await someOtherGraphQLCall(data.foo);
    return { someOtherData };
}
2 голосов
/ 03 июля 2019

Если вам интересно, есть ли способ достичь этого без else, да, это так. Но, это может быть не самым чистым способом. ИМО, использование return - лучший способ остановить выполнение контроллера.

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

В вашем примере выделите data = await someGraphQLCall(); следующим образом:

const middlewareOne = async function(req, res, next) {
    let data = [];
    let response = { message: "No data." };
    try {
        data = await someGraphQLCall();
        req.locals.data = data; // <- attach the data to req.locals
    } catch (err) {
        response = { err };
    }
    data.length === 0 ? res.json(response) : next();
};

А затем смонтируйте middlewareOne ДО вашего контроллера:

app.get("/matches", middlewareOne, async function controller(req, res) {
    try {
        const someOtherData = await someOtherGraphQLCall(req.locals.data.foo);
        res.json({ someOtherData });
    } catch (err) {
        res.json({ err });
    }
});

Как это работает, функция controller будет выполняться только экспрессом, если next() вызывается из предыдущего промежуточного программного обеспечения - middlewareOne в примере.
И поскольку middlewareOne только вызывает next(), если data.length не равен 0, он будет работать так, как вы ожидали.


Для получения дополнительной информации о передаче данных из одного промежуточного программного обеспечения в другое читайте this

0 голосов
/ 27 июня 2019

Оператор return прекращает выполнение функции в этом контексте. На мой взгляд, вы должны обработать случай успеха, а затем случай ошибки, поскольку код будет читаться сверху вниз.

В операторе if данные могут быть undefined или null.

Подробнее можно прочитать здесь: MDN - возврат

app.get('/matches', async function(req, res) {
  try {
    const data = await someGraphQLCall();

    // alternative, if (data && data[0]) {
    if (data && data.length) {
      const someOtherData = await someOtherGraphQLCall(data.foo);
      return res.json({ someOtherData });
    }

    return res.json({ message: "No data." });
  } catch (err) {
    console.log(err); // log error with logger and drain to loggly.
    res.json({ err })
  }
} 

С оператором Void:

Оператор Void позволяет вернуть неопределенное значение, но оценить данное выражение.

Вы можете прочитать больше здесь: MDN - Void

app.get('/matches', async function(req, res) {
  try {
    const data = await someGraphQLCall();

    // alternative, if (data && data[0]) {
    if (data && data.length) {
      const someOtherData = await someOtherGraphQLCall(data.foo);
      return void res.json({ someOtherData });
    }

    return void res.json({ message: "No data." });
  } catch (err) {
    console.log(err); // log error with logger and drain to loggly.
    res.json({ err })
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...