[英]Knowing when forEach loop finished
我怎么知道我的代码何时完成循环? 完成后,我必须运行更多代码,但只有在我在那里编写的所有内容都完成后才能运行。
obj.data.forEach(function(collection) {
var serialized_array = collection['quiz_ids'];
quiz_collections.push([collection['id'], collection['name'], collection['type'], collection['category'], serialized_array.split(',')]);
serialized_array.split(',').forEach(function(ite) {
query('./php/query.php', 2, [['quiz_id', ite]]).then(function(quiz_obj) {
if (quiz_obj.data[0] == 'false') {
}
else {
fetch(quiz_obj.data[0]['data']).then(function(resp) {
return resp.json();
})
.then(function(data) {
console.log(data);
quiz_data.push([quiz_obj['id'], quiz_obj['name'], quiz_obj['version'], quiz_obj['data'], data]);
});
}
});
});
});
如果有帮助。 第一行中的 obj.data 如下所示:
这是我的查询功能:
function query(url, cmd_type, data_array) {
var request = new XMLHttpRequest();
var params= '';
params = params + 'cmdtype=' + encodeURIComponent(cmd_type) + '&';
if (data_array) {
data_array.forEach(function(item) {
params = params + item[0] + '=' + encodeURIComponent(item[1]) + '&';
});
}
console.log(params);
return new Promise(function(resolve, reject) {
request.open('POST', url, true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.onreadystatechange = function() {
if (request.readyState === XMLHttpRequest.DONE) {
if (request.status === 200) {
var response = JSON.parse(request.response);
resolve(response);
}
else {
resolve({error: 'Cant connect!'});
}
}
};
request.send(params);
});
}
提前致谢
菲利普
您可以使用reduce一个接一个地运行 promises 而不是forEach 。
例子:
const data = [1, 2, 3, 4, 5];
const loopResult = data.reduce(async (previous, value) => {
// Wait for previous loop to finish
await previous;
// Return new promise
return new Promise((resolve) => {
// Promise code
// Make HTTP fetch here...
resolve();
});
}, Promise.resolve());
loopResult.then(() => {
console.log('loop finished');
});
或者,如果您的循环不需要按顺序排列,您可以使用Promise.all :
const loopResult = Promise.all(
data.map((value) => new Promise((resolve) => {
// Promise code
// Make HTTP fetch here...
resolve();
}))
);
loopResult.then(() => {
console.log('loop finished');
});
一种方法是Promise.all 。
您可以将您的 fetch 承诺推送到一个数组中,一旦 forEach 循环完成,就调用 Promise.all :
const promises = [];
// start loop
const promise = query(...);
promises.push(promise);
// end loop
Promise.all(promises).then((values) => doSomething(values));
这解决了您的问题,但是有更好的方法可以做到这一点,例如使用RxJS forkJoin 。 RxJS 在处理更复杂的异步代码时非常有用。
承诺应该有一个 .then 方法,它在完成时被调用。 then 方法将接收一个函数来调用。
var promise = // your code that gets the promise ( a call to query)
promise.then((values) => {//code to run afterwards})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.