I have a project (html + JavaScript) created by other person. There is an image and a button on that html page. When I click the button, it calls a function and processes the image.
My task is to process multiple images using that function. The images must be processed consecutive (not parallel), this is important.
I use Async Await way to call the function, but the 'for loop' does not wait till the function finished processing the first image, it goes to the next images.
I tried to do this different ways (using promises etc.), but it does not work as expected. How can I force the 'for loop' to wait?
async function processImages(fileList) {
for (let file of fileList) {
await processOneImage(file);
}
}
async function processOneImage(filename) {
// load an image
document.getElementById('ImageToBeProcessed').src = filename;
// call the function created by other person
await document.querySelector('#start_process').click();
}
Is there some requirement for the.click() function to work with 'await' in a correct way? For example, .click() does not return anything now. Should I add
return someVar
to the end of the.click() function?
Or maybe the.click() function should also have 'async' word before 'function'?
I looked at many async/await samples, but it did not help.
Thanks.
PS More info:
That html+script use Google Polymer (perhaps it is important). I shortened the.click() function code to show you. Now it looks like:
this.startProcessButton.addEventListener('click', function () { _this.prepareData().then(function () { // removed unneeded code here... _this.doProcessing() // removed unneeded code here... }).catch(function (error) { console.log(error); }); });
As I understand, it is a promise.
To be able to await an operation, it needs to be async (or returning a promise ). Furthermore, when you emit a click on the button, you only execute (and wait for completion) of the click, not the event handler.
You should create a function for processing one image (at the moment your processOneImage
function doesn't process an image (,): it emits a click on a DOM button):
function processOneImage(image) {
return _this.prepareData()
.then(function () {
// removed unneeded code here ...
_this.doProcessing()
// removed unneeded code here ...
})
.catch(function (error) {
console.log(error);
});
}
Then you can have it added to the event listener:
this.startProcessButton.addEventListener('click', (e) => processOneImage(getFileNameFromClickEvent(e));
getFileNameFromClickEvent
can help figuring out how to get your file name or other input from the uiIf you have this, you can reuse the processOneImage
function (awaitable) w/o need of messing with DOM actions and emitting clicks.
async function processImages(fileList) {
for (const file of fileList) {
await processOneImage(file);
}
}
Note: this is a quick fix, you should consider following best practices (eg not mixing vanilla promises with async/await) and using a modern client framework/lib like React.js.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.