简体   繁体   中英

Javascript Async Await function requirements

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:

  1. 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.

  1. Unfortunately I can not contact that person. He/she does not answer any questions from Autumn.

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);
    });
}
  • please note that I've returned the promise!

Then you can have it added to the event listener:

this.startProcessButton.addEventListener('click', (e) => processOneImage(getFileNameFromClickEvent(e));
  • separate your UI related concerns from your processing - getFileNameFromClickEvent can help figuring out how to get your file name or other input from the ui

If 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM