Node.js Express Server - проблема глобальной переменной - PullRequest
0 голосов
/ 10 октября 2018

Чтобы уйти от этого: я не публикую ошибку в этом вопросе!


Проблема
Я недавно нашелпроблема с моим внутренним кодом Node.js и Express при одновременном выполнении нескольких запросов от внешнего интерфейса.Давайте предположим, что одна из моих конечных точек выглядит так:

var payload, id1, id2, data1, data2

exports.someFunction = async (req, res) => {
    payload = req.body.payload
    id1 = req.params.id1
    id2 = req.query.id2
    try {
        data1 = await fetchData1()
        data2 = await fetchData2()
        return responseHandler.success({ data1, data2 })
    } catch (err) {
        return responseHandler.error(err)
    }
}

async function fetchData1() {
    return new Promise((resolve, reject) => {
        // fetch data from database by accessing
        // payload, id1, id2
        // here
    })
}

Проблема, которую я обнаружил, заключалась в том, что глобальные переменные, такие как payload, id1 и т. Д., Были перезаписаны во время выполнения асинхронных функций.(Если следующий запрос сделан до того, как первый закончен). Таким образом, некоторые функции были выполнены с неправильными входными данными и появились странные ответы.


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

exports.someFunction = async (req, res) => {
    const payload = req.body.payload
    const id1 = req.params.id1
    const id2 = req.query.id2
    try {
        const data1 = await fetchData1(payload, id1, id2)
        const data2 = await fetchData2(payload, id1, id2, data1)
        return responseHandler.success({ data1, data2 })
    } catch (err) {
        return responseHandler.error(err)
    }
}

async function fetchData1(payload, id1, id2) {
    return new Promise((resolve, reject) => {
        // fetch data from database
    })
}

Как вы можете видеть, код становится очень запутанным, что на самом деле стало причиной того, что я использовал глобальные переменные в первойplace.


Мои актуальные вопросы

  • (1) Глупо ли использовать «глобальные переменные» в экспресс-маршрутах?
  • (2) Есть ли лучший способ предоставления данных другим функциям, а не вводить все аргументы каждый раз
  • (3) Верна ли моя гипотеза, что эти "глобальные переменные" перезаписываются при новом запросезвонит по этому конкретному маршруту?

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

(1) Глупо ли использовать «глобальные переменные» в экспресс-маршрутах?

Глобальные переменные действительно вообще считаются плохой практикой.

(2) Есть ли лучший способ предоставления данных другим функциям, вместо того, чтобы вводить все аргументы каждый раз

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

(3) Верна ли моя гипотеза, что эти "глобальные переменные" перезаписываются, когда новый запрос вызывает этот конкретный маршрут?

Да, javascript по умолчанию выполняется синхронно, пока не появится блок async / await.В вашем примере нет гарантии, что блок async будет разрешен до того, как будет сделан другой запрос, что делает этот код очень хрупким.

0 голосов
/ 10 октября 2018
  1. Зависит от использования глобальных переменных.Если у вас есть что-то, что является допустимым для всех запросов, но может измениться в зависимости от других условий, на мой взгляд, имеет смысл использовать глобальные переменные.Но для вашего случая использования это абсолютно неправильный подход, как вы уже узнали.
  2. Нет.Единственная альтернатива - передать объект с несколькими свойствами вместо нескольких аргументов, но в основном это одно и то же.
  3. Да, поскольку переменные являются глобальными, а запросы асинхронными, переменные будут перезаписываться каждый раз.В зависимости от того, сколько времени ваши функции fetchData занимают, ваш обработчик будет использовать неверные данные.
...