Я новичок в мире javascript, у меня есть такой простой метод
function foo(items) {
var result = []
// Assume under forEach statement take 2 sec per loop
items.forEach(function(item) {
setTimeout(function() {
result.push(item + 2)
}, 2000)
})
return result
}
console.info(foo([1,2,3,4]))
console.info("Done")
Результат:
[]
Done
Кроме вывода:
[ 3, 4, 5, 6 ]
Done
кто-нибудь может мне помочь или объяснить мне об асинхронности в javascript, чтобы решить эту проблему.
Зачем тебе setTimeout? Если вам это нужно, проверьте связанный вопрос. Он предоставляет вам подробные объяснения того, как вы можете обрабатывать асинхронность в javascript.
@YuryTarabanko @MaxBaldwin на самом деле, в цикле требуется некоторое время, прежде чем элемент push появится в результате, например, для запроса или чего-то, что требует времени.
@ 6LYTH3 Тогда вам нужно проверить связанный вопрос :)



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


Избавьтесь от setTimeout, и он должен работать так, как вы ожидаете:
function foo(items) {
var result = []
// Assume under forEach statement take 2 sec per loop
items.forEach(function(item) {
result.push(item+2)
})
return result
}
console.info(foo([1,2,3,4]))
console.info("Done")
Возвращает [3, 4, 5, 6]
И используйте метод .map или .reduce, если вы просто хотите вернуть массив.
Попробуйте следовать
function foo(items) {
var result = []
// Assume under forEach statement take 2 sec per loop
items.forEach(function(item) {
// Create a promise for each async function
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(item + 2); // resolve the async function
}, 2000);
});
result.push(promise); // push the promise into array
});
// Create one promise for all the promises and return
return Promise.all(result)
}
// Now, foo function returns a promise and then is called once the promise is resolved which contains the data
foo([1,2,3,4]).then((response) => console.info(response)).then(() => console.info("Done"));Поскольку setTimeout является функцией ansync, т.е. она выполняется не по порядку, следовательно, как и ожидалось, на выходе был пустой массив (когда массив был возвращен, обратный вызов функции setTimeout не выполнялся). Вы можете использовать Обещания для работы с функцией async.
Большое усилие! Используйте .map
Хорошо выглядишь для меня, foo([1,2,3,4]).then((response) => console.info(response)).then(() => console.info("Done"))
@ 6LYTH3 - Согласен. Обновлено. Спасибо.
@MaxBaldwin - Идея заключалась в том, чтобы понять функцию async, а не делать какой-то addition in timeout. Для одного и того же есть много подходов, я выбрал тот, который мне было легко объяснить :)
Использует Array.map для вставки элементов:
function foo(items) {
var result = []
items.map(_=>result.push(_+2))
return result
}function foo(items) { // start function
var result = [] // the result array
items.map(_=>result.push(_+2)) // map over array and for every element set it equal to that element + 2
return result; // return resultant array
} // end function
foo = items => items.map(_=>_+2)
console.info(foo([1,2,3,4,5]))Действительно? map для отправки на внешний массив. Почему??? :)
@YuryTarabanko: Отредактировал доп. И почему голосование против?
На самом деле, я не голосовал против :) Но я согласен с тем, кто проголосовал против: продвигать map для создания побочных эффектов - плохая идея.
Это из-за
setTimeout. Вы помещаете асинхронный код в синхронный цикл. Можно ли избавиться от тайм-аута?