javascript - 循环后执行的循环中的 Promise 回调
问题描述
我习惯于等待,但 eslint 讨厌它循环。Eslint 也不喜欢在循环中定义函数。因此,我在 Vuex 脚本中得到了以下代码段:
// wait until the file is synchronized
let waitTime = 100;
let fileExists = false;
const checkSync = (res, i) => {
console.log(res.status);
if (res.status === 200) {
fileExists = true;
console.log('Status 200, setting fileExists=true');
} else if (res.status === 404) {
Vue.$log.debug(`Image not ready for download ${res.status}`);
setTimeout(() => { waitTime = (i < 4) ? 200 : 1000; }, waitTime);
console.log(`waitTime = ${waitTime}`);
}
};
for (let i = 0; !fileExists && i < 5; i += 1) {
console.log(`fileExists = ${fileExists}`);
axios.head(`${response.data.data.url}`).then(resp => checkSync(resp, i));
}
但是日志显示循环内的第一个日志语句是一个接一个地执行的,而带有 promise/resolve 的第二个语句是在循环完成时执行的。我可以重写代码来等待并忽略 eslint,但我希望我最终能更深入地了解古老的承诺。
fileExists = false
fileExists = false
fileExists = false
fileExists = false
fileExists = false
items.js:175 200
items.js:178 Status 200, setting fileExists=true
items.js:175 200
items.js:178 Status 200, setting fileExists=true
items.js:175 200
items.js:178 Status 200, setting fileExists=true
items.js:175 200
items.js:178 Status 200, setting fileExists=true
items.js:175 200
items.js:178 Status 200, setting fileExists=true
更新
我通常这样做的方式。Eslint 抱怨,但代码是由用户在上传新图片时触发的,所以我不需要关心效率。
// wait until the file is synchronized on backend to www node
let waitTime = 100;
for (let i = 0; i < 5; i += 1) {
// eslint-disable-next-line no-await-in-loop
const head = await axios.head(response.data.data.url);
if (head.status === 200) {
return response.data;
} else if (head.status === 404) {
Vue.$log.debug(`Image not ready for download ${head.status}`);
// eslint-disable-next-line no-loop-func
setTimeout(() => { waitTime = (i < 4) ? 200 : 1000; }, waitTime);
console.log(`waitTime = ${waitTime}`);
}
}
解决方案
// This function does promised function from array one-by-one
const reducePromise = (items = [], callback) => (
items.reduce(async (promisedAcc, curr) => {
const acc = await promisedAcc;
const currentResult = await callback(curr);
return acc.concat(currentResult);
}, Promise.resolve())
)
// This Function resolves promise after time that passed by param
const wait = (time = 0) => new Promise((resolve) => setTimeout(() => resolve(), time))
let fileExists = false;
reducePromise([...Array(5).keys()], async (i) => {
await axios.head(`${response.data.data.url}`)
.then(res => {
fileExists = true;
console.log('Status 200, setting fileExists=true');
})
.catch(({ response: res }) => {
Vue.$log.debug(`Image not ready for download ${res.status}`);
const waitTime = (i < 4) ? 200 : 1000;
return wait(waitTime)
})
})
推荐阅读
- python - 为什么没有评论被打印出来?我是否使用了正确的 HTML 元素?
- numpy - np.column_stack 是如何工作的?我正在为不同的例子获得奇怪的输出
- python - Python libusb给我OSError:异常:访问冲突读取
- android - 使用位图对 SwitchCompat 进行自定义
- python-3.x - Pandas 数据框空间分隔符
- javascript - 如何在 React 中 Jest / Enzyme 测试带有Router() 包装的组件的 react-router-dom?
- php - CSS 设计以按组 ID 显示数据行的替代颜色
- javascript - Nuxt 页面转换在本地工作,但不适用于 Firebase 托管
- solr - SOLR 8:无法查询字段内容
- python - 在 python 中并排显示图像