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



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


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;
}
Для поиска вашего собственного ответа все остальные используют термин «асинхронный», а не «А-синхронизация» ...