如何等到所有的承诺完成
How to wait until all the promises finish
假设,我们想在上传图片之前检查图片的宽度。 Here is the fiddle。最后我们需要等待所有的异步操作结束。为此,我尝试使用 Promises。但是,不幸的是,good_images 里面的 alert 是空的。看来,我错过了一些简单的东西。
我试过Promise.all,但还是不行。 Fiddle.
$(document).ready(function () {
function check_image_dimensions ($this, image, img_name) {
let min_width = + $this.data('min_width');
if (typeof(min_width) === "number" && image.width < min_width) {
alert(`Error loading photo ${img_name}, image width: ${image.width}px is less then minimal: ${min_width}px.`);
return false;
}
return true;
}
function unknown_error () {
alert('Unknown error while loading image.');
}
$(document).on('change', '.upload_images', function() {
var $this = $(this);
let images = $this.prop('files');
if (typeof(images) === 'undefined' || images.length === 0) {
return false;
}
let good_images = Array();
let promise = Promise.resolve();// <- I tried this, but it is wrong
for (let i = 0; i < images.length; i++) {
let promise = new Promise(function(resolve, reject) {
const reader = new FileReader();
reader.onload = resolve;
reader.readAsDataURL(images[i]);
});
promise.then((event) => {
const img = new Image();
img.onload = () => {
if(check_image_dimensions($this, img, images[i].name) === true) {
good_images.push(i);
}
};
img.onerror = unknown_error;
img.src = event.target.result;
return i;
}).catch(unknown_error);
}
promise.then(() => alert(good_images));
});
});
问题是您只是调用“then”而没有再次设置变量。请参阅以下示例。
let arrdata = [1,2,3,4];
let prom = Promise.resolve();
arrdata.map(data => {
// Here's the deal
prom = prom.then(() => {
console.log(data);
});
});
prom.then(() => console.log('end'));
如果您想并行处理所有这些图像,您可以创建一个承诺数组并使用 Promise.all
等待它们。请注意,在处理您的图像时,您还需要将该部分包装在一个承诺中:
const good_images = [];
const promises = [];
for (let i = 0; i < images.length; I++) {
const image = images[I];
let promise = new Promise( ... );
promise = promise.then((event) => {
const img = new Image();
img.src = event.target.result;
return new Promise(resolve => {
img.onload = () => {
if (is_good(img)) {
good_images.push(i);
}
resolve();
};
});
})
promise = promise.catch(() => { ... });
promises.push(promise);
});
Promise.all(promises).then(() => alert(good_images));
假设,我们想在上传图片之前检查图片的宽度。 Here is the fiddle。最后我们需要等待所有的异步操作结束。为此,我尝试使用 Promises。但是,不幸的是,good_images 里面的 alert 是空的。看来,我错过了一些简单的东西。
我试过Promise.all,但还是不行。 Fiddle.
$(document).ready(function () {
function check_image_dimensions ($this, image, img_name) {
let min_width = + $this.data('min_width');
if (typeof(min_width) === "number" && image.width < min_width) {
alert(`Error loading photo ${img_name}, image width: ${image.width}px is less then minimal: ${min_width}px.`);
return false;
}
return true;
}
function unknown_error () {
alert('Unknown error while loading image.');
}
$(document).on('change', '.upload_images', function() {
var $this = $(this);
let images = $this.prop('files');
if (typeof(images) === 'undefined' || images.length === 0) {
return false;
}
let good_images = Array();
let promise = Promise.resolve();// <- I tried this, but it is wrong
for (let i = 0; i < images.length; i++) {
let promise = new Promise(function(resolve, reject) {
const reader = new FileReader();
reader.onload = resolve;
reader.readAsDataURL(images[i]);
});
promise.then((event) => {
const img = new Image();
img.onload = () => {
if(check_image_dimensions($this, img, images[i].name) === true) {
good_images.push(i);
}
};
img.onerror = unknown_error;
img.src = event.target.result;
return i;
}).catch(unknown_error);
}
promise.then(() => alert(good_images));
});
});
问题是您只是调用“then”而没有再次设置变量。请参阅以下示例。
let arrdata = [1,2,3,4];
let prom = Promise.resolve();
arrdata.map(data => {
// Here's the deal
prom = prom.then(() => {
console.log(data);
});
});
prom.then(() => console.log('end'));
如果您想并行处理所有这些图像,您可以创建一个承诺数组并使用 Promise.all
等待它们。请注意,在处理您的图像时,您还需要将该部分包装在一个承诺中:
const good_images = [];
const promises = [];
for (let i = 0; i < images.length; I++) {
const image = images[I];
let promise = new Promise( ... );
promise = promise.then((event) => {
const img = new Image();
img.src = event.target.result;
return new Promise(resolve => {
img.onload = () => {
if (is_good(img)) {
good_images.push(i);
}
resolve();
};
});
})
promise = promise.catch(() => { ... });
promises.push(promise);
});
Promise.all(promises).then(() => alert(good_images));