Как сделать этот цикл async foreach с помощью promises?
Я уже перепутал с Promises в нем, но я новичок в них, и я просто не могу понять, как это сделать должным образом. На данный момент нет смысла в Promise, потому что он не ждет завершения async $.get
.
В принципе, каждая итерация foreach
имеет свою собственную функцию $.get
, и мне нужно, чтобы все они были заполнены, а затем продолжаем часть, которая имеет "... получает альбом" console.log
.
$.get(id,function(data) {
//(there some code here)
var getZippyUrls = new Promise(function(resolve) {
zippyarray.forEach(function(zippy) {
//(more code)
$.get(zippy.full, function(data) {
//^This is the foreach of $.gets
//(code here)
});
resolve(zippyarray);
});
});
//This is my failed Promise ->
getZippyUrls.then(function(response) {
console.log("WE'RE OUT " + response.length);
response.foreach(function(d) {
console.log("Promise"+d.media);
});
console.log('eyyyyyy');
});
console.log("...gets albumart");
//Now after the previous stuff is done, move on
Ответы
Ответ 1
В синхронном коде продолжение продолжается, когда заканчивается строка ;
С promises продолжение выполняется через .then
. Вы использовали конструктор обещаний и сразу решили, вы не дождались какой-либо задачи. Я сопоставлял свою работу с задачами, а затем либо связывал их с ними, либо ожидал их поочередно.
//I'm assuming
zippyarray; // array of Zippy objects
var tasks = zippyarray.map(function(zippy,i){
return function(){ // return a task on that zippy;
// basic logic here
return $.get({
// ajax request
}).then(function(data){
// process data like in your code
// possibly store later for later use too
return process(data); // return the processed data;
});
}
});
Теперь мы можем выполнить их последовательно:
var p = tasks[0](); // start the first one
for(var i = 1; i < tasks.length; i++) p = p.then(tasks[i]);
p.then(function(result){
// all available here
});
Или лучше, серийно:
$.when.apply(tasks.forEach(function(t){ return t(); })).then(function(results){
// all done
})
Ответ 2
Я знаю, что это старый вопрос, но в последнее время все изменилось.
Если вам хорошо с использованием внешних библиотек, библиотека обещаний Bluebird имеет довольно хорошую реализацию для этого: Promise.each.
например.
function helperFunc(zippyarray) {
return Promise.each(zippyarray, zippy => {
return someOperationThatReturnAPromise(zippy)
.then((singleResult) => {
// do something with the operation result if needed
})
}).then((originalArray) => {
// this happens only after the whole array is processed
// (result is the original array here)
return Promise.resolve(originalArray)
})
}
Ответ 3
Чтобы отслеживать несколько запросов get-Requests, вы используете этот способ:
var cnt = requestCnt;
function finished(){
if(--cnt)return;
// Your code here
}
for(var i = 0; i < requestCnt; ++i){
$.get('something.htm', {data:data}, function(data){
finished();
});
}
Вы всегда вызываете законченную функцию, когда запрос получает ответ. Готовая функция выполняет задание, когда все делается.
Ответ 4
Сегодня, если мне нужно сделать это последовательно - я бы сделал это с помощью async/await
:
//I'm assuming I'm inside an `async` function
zippyarray; // array of Zippy objects
for(const task of zippyArray) {
const result = await $.get({ ... });
// do stuff with result
}