#javascript #node.js #arrays #reactjs #express
#javascript #node.js #массивы #reactjs #экспресс
Вопрос:
Я извлекаю данные с моего серверного сервера node (express) для интерфейса react. Но когда я пытаюсь получить доступ к значениям индекса массива, я получаю вывод как неопределенный. Я уверен, что здесь что-то не так. Буду признателен, если кто-нибудь сможет мне помочь.
Вот мой код на стороне сервера:
const companyDetails = [];
companies.forEach((company) => {
companyDetails.push(company);
});
app.get("/api/companies", (req, res) => {
res.json(companyDetails)
});
Вот мой код на стороне клиента:
let arr = [];
function fetchComNames() {
axios.get('/api/companies').then(res => {
for(let i=0; i<=4; i ) {
arr.push(res.data[i].name)
}
})
}
fetchComNames();
console.log(arr[0]); //undefined
Но когда я console.log(arr);
распечатываю массив. Я просто не могу получить доступ к каждому значению индекса отдельно.
Ответ №1:
(async () => {
const arr = [];
// Marking this function as async function so that
// we can use await to wait until result returning
// before further executing code below
async function fetchComNames() {
// I don't have access to you API
// I resolve data after 1 second to simulate Ajax call here
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve({
data: [{
name: "1"
}, {
name: "2"
}, {
name: "3"
}, {
name: "4"
}]
});
}, 1000);
}).then(res => {
return res.data.map(each => each.name)
});
}
// You are calling Ajax call via Axios, which is a Promise.
// It is executed asyncrhoniously.
// If you need to use result from this call,
// you need to wait until result returning from async call.
// You can achieve it with await.
// Update existing array
arr.push(...(await fetchComNames()));
// After await, arr should contain result you expected.
console.log(arr[0]);
// There reason why your version is not working
// is because you are accessing the first cell of arr
// wihich is still empty as the Axios is still running
// and you are not waiting until it returns result.
})();
Комментарии:
1. Большое спасибо за объяснение. Но мне нужно получить доступ к значениям этого массива из этой функции. Кажется, я не могу сделать это вне этой функции. Могу ли я как-нибудь это сделать?
2. Пожалуйста, дайте мне больше кода. Если все, что вам нужно, это добавить больше элементов в существующий массив, это не проблема, я обновлю свой код
3. Это решает мою проблему, большое спасибо, вы очень помогли!
Ответ №2:
Проблема здесь в том, что axios
вызов — это async
вызов, и выполнение вашего кода таково sync
, что при выполнении этого кода javascript
sync
сначала выполняется код, а затем async
тот, поэтому в этом случае строка кода onsole.log(arr[0]);
выполняется до того, как ответ придет с сервера
Ответ №3:
Вызовы API являются асинхронными, поэтому вы обращаетесь к массиву до того, как в нем появятся его значения. Попробуйте пометить свою заключающую функцию как асинхронную и ожидать получения axios, чтобы вызов был принудительно синхронным.
let arr = [];
async function fetchComNames() {
const fetched = await axios.get('/api/companies');
for(let i=0; i<=4; i ) {
arr.push(fetched.data[i].name)
}
}
fetchComNames();
console.log(arr[0])
Комментарии:
1. Тем не менее, это даст
undefined
Ответ №4:
Добавление к приведенному ниже ответу fetchComNames
асинхронно обновляется arr
при использовании вызова API. Вы получаете доступ к данным до того, как они были обновлены, поэтому получаете undefined
.
Вы можете попробовать это.
const fetchComNames = async () => {
try {
const response = await axios.get('/api/companies')
const array = response.data.map(c => c.name)
OR
const array = []
for (let i = 0; i<= 4; i ) {
array.push(response.data[i].name)
}
console.log(array[0])
} catch(err) {
console.error(err)
}
}
fetchComNames()