Node.JS / Express - Почему A-Sync запускается в случайном порядке?

Недавно я начал использовать Node.js / Express. Я понимаю, что вызов A-Sync должен завершиться, прежде чем он сможет продолжить. В моем коде есть три разных конечных точки, которые мне нужно поразить.

Поскольку я принял во внимание A-Sync, я попытался закодировать его, чтобы он выполнял их в том порядке, в котором они представлены.

Однако он попадает в первую конечную точку, затем в третью, а затем во вторую. Я понимаю, что это должно быть проблема в моем коде, но я занимаюсь этим несколько часов.

Где я ошибся? Почему он оставляет вторую конечную точку напоследок?

app.get("/start/:origin/:destination", function ( reqt, resp ) {
var origin = reqt.params.origin
var destination = reqt.params.destination
var url = 'http://localhost:5000/maps/' + origin + '/' + destination 

var rate;
var overallDis;
var aRoadDis;

var data;
http.get(url, res => {
    res.setEncoding('utf8')
    res.on('data', function(body){
        data = JSON.parse(body)
        overallDis = data["distance"]
        aRoadDis = data["ARoads"]
    })
})

var driver;
http.get("http://localhost:4000/lowestRate/", res => {
    res.setEncoding('utf8')
    res.on('data', function(body){
        driver = JSON.parse(body)
        rate = driver.rate
        console.info(rate)
    })

})

var totalPrice = 0
http.get("http://localhost:6000/surge/:" + rate + "/:" + overallDis + "/:" + aRoadDis, res => {
    // console.info(overallDis)
    // console.info(aRoadDis)
    // console.info(rate)
    res.setEncoding('utf8')
    res.on('data', function(body){
        console.info(body)
        totalPrice += parseInt(body)
    })
    console.info(totalPrice)
})

})

Для поиска вашего собственного ответа все остальные используют термин «асинхронный», а не «А-синхронизация» ...

Heretic Monkey 15.03.2018 22:43

Не знаю, откуда у вас идея, что «вызов A-Sync должен завершиться, прежде чем он сможет двигаться дальше». Это в значительной степени противоположное тому, что на самом деле происходит! Асинхронная функция вернется почти сразу, но код обратного вызова будет выполнен только после завершения асинхронной функции (в данном случае HTTP-вызовов). Порядок результатов, вероятно, определяется тем, сколько времени требуется для выполнения «удаленного» кода.

lonesomeday 15.03.2018 22:43

использовать с await

Ivan 15.03.2018 23:06

Спасибо вам всем! Не осознавал, что мои знания были настолько неправильными!

JoeBoggs 16.03.2018 11:14
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
81
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

I understand an A-Sync call must complete before it can move on.

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

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

Вот хорошая ссылка для изучения цикла событий Javascript. https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop

Надеюсь, это поможет!

PS: Если вы хотите дождаться завершения одного запроса, прежде чем переходить к остальным, я бы предложил Обещания.

app.get("/start/:origin/:destination", function ( reqt, resp ) {
    const origin = reqt.params.origin
    const destination = reqt.params.destination
    const url = 'http://localhost:5000/maps/' + origin + '/' + destination
    const totalPrice = 0

    const firstPromise = new Promise((resolve, reject) => {
      http.get(url, res => {
        res.setEncoding('utf8')
        res.on('data', function(body){
          data = JSON.parse(body)
          resolve({
            overallDis: data["distance"],
            aRoadDis: data["ARoads"]
          });
        })
      })
    });

    const secondPromise = new Promise((resolve, reject) => {
      http.get("http://localhost:4000/lowestRate/", res => {
        res.setEncoding('utf8')
        res.on('data', function(body){
          const driver = JSON.parse(body)
          const rate = driver.rate
          console.info(rate)
          resolve(rate);
        })
      })
    });

    Promise.all([firstPromise, secondPromise]).then((values) => {
      // This will fire after both promises have called resolve()
      const overallDis = values[0].overallDis;
      const aRoadDis   = values[0].aRoadDis;
      const rate       = values[1];

      http.get("http://localhost:6000/surge/:" + rate + "/:" + overallDis + "/:" 
        + aRoadDis, res => {
          // console.info(overallDis)
          // console.info(aRoadDis)
          // console.info(rate)
          res.setEncoding('utf8')
          res.on('data', function(body){
            console.info(body)
            totalPrice += parseInt(body)
          })
          console.info(totalPrice)
      })
    });
})

Как упоминается в других ответах, ваша интерпретация async неверна: синхронные вызовы блокируют выполнение следующего кода, тогда как асинхронные вызовы нет.

Если вы хотите выполнить свои операции по порядку, но на самом деле они асинхронны, самый простой способ - использовать обратные вызовы. Это выполнимо для небольших стеков вызовов, но не зря это называется callback-hell.

Лучшим способом было бы обернуть асинхронные вызовы в Promises, а затем использовать структуру async / await для их синхронного упорядочения. Это могло выглядеть примерно так.

async function (req, res) {
    let op_1_result = await new Promise(function(resolve, reject) {
        ... do your async operation and finally call
        resolve(response);
    });

    ... do your other operations in the same fashion

    let op_n_result = await new Promise(function(resolve, reject) {
        ... do your async operation and finally call
        resolve(response);
    });
    return op_n_result;
}

Другие вопросы по теме