在执行下一个函数之前等待循环完成填充数组
wait for loop to finish populating array before executing next function
我试图在这个循环之后访问 imgArr
,当然我得到的是空数组,因为 console.log(imgArr)
是与 for 循环同步执行的。
但是我需要填充 imgArr
才能在其他逻辑中使用。
我不能再次使用 setTimeout,因为我不知道完成循环需要多少时间。
我试图将所有这些包装在一个函数中并在另一个函数中调用它,但无济于事
var imgArr = []
var nextBtn = document.querySelector('[aria-label="Next"]')
for (var i = 0; i < 15; i++) {
setTimeout(() => {
if (nextBtn) {
Object.values(document.querySelectorAll('img')).map(img => {
if (imgArr.indexOf(img.src) === -1) imgArr.push(img.src)
});
nextBtn.click();
nextBtn = document.querySelector('[aria-label="Next"]');
};
}, i * 1000);
};
console.log(imgArr) // expected: [], needed: [element1, element2, ...]
您可以像这样修改您的代码
imgArray 是一个 promise,因此您不能直接访问解析后的值
var nextBtn = document.querySelector('[aria-label="Next"]')
const imgArray = Promise.all(Array(15).fill(0).map((_, i) => new Promise(resolve => {
let array = []
setTimeout(() => {
if (nextBtn) {
array = Object.values(document.querySelectorAll('img')).map(img => img.src);
nextBtn.click();
nextBtn = document.querySelector('[aria-label="Next"]');
};
resolve(array)
}, i * 1000);
}))).then(data => [...new Set(data.flat())])
imgArray.then(d => console.log(d)) // expected: [], needed: [element1, element2, ...]
函数在 setTimeout 调用之前执行,将其转换为 Promise 将很容易处理
let result = [];
const nextClick = (res) => {
const nextBtn = document.querySelector('[aria-label="Next"]');
if (nextBtn) {
const imgs = Object.values(document.querySelectorAll("img"));
result = Array.from(new Set([...result, ...imgs.map((img) => img.src)]));
nextBtn.click();
nextBtn = document.querySelector('[aria-label="Next"]');
}
res(result);
};
const wait = (ms) => new Promise((res) => setTimeout(() => nextClick(res), ms));
const promiseArr = new Array(15).fill(0).map((_, i) => wait(i * 1000));
Promise.all(promiseArr).then(() => console.log(result));
我试图在这个循环之后访问 imgArr
,当然我得到的是空数组,因为 console.log(imgArr)
是与 for 循环同步执行的。
但是我需要填充 imgArr
才能在其他逻辑中使用。
我不能再次使用 setTimeout,因为我不知道完成循环需要多少时间。
我试图将所有这些包装在一个函数中并在另一个函数中调用它,但无济于事
var imgArr = []
var nextBtn = document.querySelector('[aria-label="Next"]')
for (var i = 0; i < 15; i++) {
setTimeout(() => {
if (nextBtn) {
Object.values(document.querySelectorAll('img')).map(img => {
if (imgArr.indexOf(img.src) === -1) imgArr.push(img.src)
});
nextBtn.click();
nextBtn = document.querySelector('[aria-label="Next"]');
};
}, i * 1000);
};
console.log(imgArr) // expected: [], needed: [element1, element2, ...]
您可以像这样修改您的代码
imgArray 是一个 promise,因此您不能直接访问解析后的值
var nextBtn = document.querySelector('[aria-label="Next"]')
const imgArray = Promise.all(Array(15).fill(0).map((_, i) => new Promise(resolve => {
let array = []
setTimeout(() => {
if (nextBtn) {
array = Object.values(document.querySelectorAll('img')).map(img => img.src);
nextBtn.click();
nextBtn = document.querySelector('[aria-label="Next"]');
};
resolve(array)
}, i * 1000);
}))).then(data => [...new Set(data.flat())])
imgArray.then(d => console.log(d)) // expected: [], needed: [element1, element2, ...]
函数在 setTimeout 调用之前执行,将其转换为 Promise 将很容易处理
let result = [];
const nextClick = (res) => {
const nextBtn = document.querySelector('[aria-label="Next"]');
if (nextBtn) {
const imgs = Object.values(document.querySelectorAll("img"));
result = Array.from(new Set([...result, ...imgs.map((img) => img.src)]));
nextBtn.click();
nextBtn = document.querySelector('[aria-label="Next"]');
}
res(result);
};
const wait = (ms) => new Promise((res) => setTimeout(() => nextClick(res), ms));
const promiseArr = new Array(15).fill(0).map((_, i) => wait(i * 1000));
Promise.all(promiseArr).then(() => console.log(result));