По какой причине работает Asny c Express Midleware? - PullRequest
1 голос
/ 11 апреля 2020

Привет, я новичок в Express / Node и искал руководство и объяснение.

Если у меня есть функция asy c в качестве промежуточного программного обеспечения, это по своей сути немедленно возвращает обещание. Давайте смоделируем функцию.

async function verifyToken() {
    try {
        await API call...
        next() // <-- continue to the next middleware if the api call was successful
    } catch (err) {
        // catch exceptions from api call
        }
    }

Мне интересно, когда я использую эту функцию следующим образом:

 this.router.get("/test", verifyToken, (req, res) => {
 res.send("GET TEST");
});

Если verifyToken asyn c, это не значит, он вызывается немедленно возвращает Promise и затем узел продолжает свое выполнение? Как асинхронные методы работают в качестве промежуточного программного обеспечения?

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Если verifyToken является asyn c, разве это не означает, что он вызывается, немедленно возвращает Promise, а затем узел продолжает свое выполнение? Как асинхронные методы работают в качестве промежуточного программного обеспечения?

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

Express предполагает в своем дизайне необходимость асинхронного промежуточное программное обеспечение (используя обещания или нет). Таким образом, он вызывает ваше промежуточное ПО, передает ему объекты req и res и обратный вызов next, а затем ничего не делает. Буквально ничего. Это делается с дальнейшей обработкой на этом этапе, пока вы не выполните одну из двух вещей - либо отправите ответ с чем-то вроде res.send(), либо позвоните next(). Если вы отправите ответ, это говорит само за себя. Если вы вызываете next(), то это говорит Express следовать цепочке обработчиков для этого запроса, найти следующий соответствующий обработчик запроса и вызвать его.

Итак, вот шаги, когда этот маршрут соответствует:

async function verifyToken(req, res, next) {
    try {
        await API call...
        next() // <-- continue to the next middleware if the api call was successful
    } catch (err) {
        // catch exceptions from api call
    }
}

this.router.get("/test", verifyToken, (req, res) => {
    res.send("GET TEST");
});
  1. nodejs первый вызов verifyToken() и его передача req, res, next.
  2. Эта функция достигает await, выполняет вызов API, приостанавливает дальнейшее выполнение функция, а затем немедленно возвращает ожидающее обещание
  3. Возврат возвращается в Express, и он просто возвращается к любому сетевому событию, сообщившему ему о входящем запросе, и больше там ничего не делать.
  4. Затем на некоторое время ничего не происходит.
  5. Затем ваш вызов API завершается в какой-то момент, и ожидаемое обещание разрешается. Это возобновляет выполнение функции в строке кода после await.
  6. Это вызывает next(), который возвращается в Express и, используя данные в замыкании для обратного вызова next(), он знает, какой обработчик вызывать следующим, и он вызывает обработчик окончательного запроса на вашем маршруте, который вызывает res.send().
  7. Этот обработчик возвращается и Express готово. Поскольку вы не вызывали next() из последнего обработчика, Express больше не будет выполнять работу над этим запросом.

Express был разработан некоторое время go и, таким образом, не врожденно обещает. Но он был спроектирован с учетом асинхронной работы, поэтому обещания по-прежнему могут отлично использоваться с инфраструктурой - вы просто подключаете обработчики событий обещаний к соответствующим обратным вызовам Express. Поскольку express не следит за обещанием, что ваша функция async вернулась, обязательно убедитесь, что вы ловите все отклонения самостоятельно, потому что Express не поймает их для вас.

Существует двоюродная сестра Express по имени koa, которая более разработана для обещаний и имеет автоматическую c обработку ошибок для отклоненных обещаний.

0 голосов
/ 11 апреля 2020

Когда в ваше приложение поступает запрос, он сначала поступает в промежуточное ПО вашего приложения, затем в промежуточное ПО маршрутизатора и, наконец, в определенную вами функцию маршрутизатора. Когда промежуточное программное обеспечение выполняется, оно только передает запрос следующему шагу, если вызывается функция next (). Значение, которое возвращает промежуточное программное обеспечение (если оно что-то возвращает), не читается и не используется какой-либо частью приложения. Я думаю, что если промежуточное программное обеспечение является асинхронным или нет, это вообще не важно, потому что express продолжит свое выполнение только после вызова функции next ().

...