Вместо ожидания запроса на разрешение (получения данных из вашего API) Node.js выполнит код снаружи и ничего не напечатает, потому что в момент выполнения ничего не происходит, и только после того, как узел получит данные изВаш API (который займет несколько миллисекунд) выполнит код внутри запроса. Это потому, что nodejs является асинхронным и неблокирующим языком, то есть он не будет блокировать или останавливать код до тех пор, пока ваш API не вернет данные, он просто продолжит работу и завершит работу позже, когда получит ответ.
Это хорошопопрактикуйтесь в том, чтобы делать все необходимые манипуляции с данными внутри функции обратного вызова, к сожалению, вы не можете полагаться на имеющуюся у вас структуру.
Вот пример вашего кода, только закомментированный порядок операций:
let data_json = ''; // global variable
app.get('/', (req, res) => {
//NodeJS STARTS executing this code
request('http://my-api.com/data-export.json', (error, response, body) => {
//NodeJS executes this code last, after the data is loaded from the server
data_json = JSON.parse(body);
console.log( data_json );
//You should do all of your data_json manipluation here
//Eg saving stuff to the database, processing data, just usual logic ya know
});
//NodeJS executes this code 2nd, before your server responds with data
//Because it doesn't want to block the entire code until it gets a response
console.log(data_json, 'Data Test - outside request code');
})
Допустим, вы хотите сделать еще один запрос с данными из первого запроса - вам нужно будет сделать что-то вроде этого:
request('https://your-api.com/export-data.json', (err, res, body) => {
request('https://your-api.com/2nd-endpoint.json', (err, res, body) => {
//Process data and repeat
})
})
Как вы можете видеть, этот шаблонможет очень быстро запутаться - это называется адом обратного вызова, поэтому, чтобы избежать большого количества вложенных запросов, есть синтаксический сахар, чтобы этот код выглядел гораздо более навороченным и поддерживаемым, он называется шаблоном Async / Await. Вот как это работает:
let data_json = ''
app.get('/', async (req,res) => {
try{
let response = await request('https://your-api.com/endpoint')
data_json = response.body
} catch(error) {
//Handle error how you see fit
}
console.log(data_json) //It will work
})
Этот код делает то же самое, что и тот, который у вас есть, но разница в том, что вы можете сделать столько await request(...)
, сколько захотите, один за другим, без вложений. Единственное отличие состоит в том, что вы должны объявить, что ваша функция асинхронная async (req, res) => {...}
и что все let var = await request(...)
должны быть вложены в блок try-catch. Это так, чтобы вы могли поймать свои ошибки. Вы можете иметь все свои запросы в блоке catch, если считаете, что это необходимо.
Надеюсь, это немного помогло:)