简体   繁体   中英

Promise in while loop javascript

I'm trying to generalize a script that encrypts forms using OpenPGP libraries. I got some troubles with the client-side code (Javascript) :

var working = formID.elements[0];
var counter = 0;

while (working) {
    encrypt(working.value).then(function(encrypted_msg) {
        console.log("processing");
        working.value = encrypted_msg;
    });
    console.log("assuming processed");
    var counter = counter + 1;
    var working = formID.elements[counter];
}

The following code should take each form element and encrypt its value. However, the while loop doesn't wait for the asynchronous encrypt() function to be resolved.

I think i need to use promises in this case, but i have no idea how and the few tutorials didn't work in a while loop.

Help ?

Probably can be used list of jQuery deferreds, something like this:

var deferreds = [];

$.each(formID.elements, function(key, working){

    var deferred = $.Deferred();
    deferreds.push(deferred);

    encrypt(working.value).then(function(encrypted_msg) {
        console.log("processing");
        working.value = encrypted_msg;
        deferred.resolve();
    });

});

$.when.apply( $, deferreds ).done(function(){
    console.log( 'after all encryptions!' );
});

Of course, can be used native Promise object instead $.Deferred , however I think $.Deferred is more cross-browser way .

UPD2:

Improved answer based on native Promise and Promise.resolve() (thanks to @Bergi). For the case when encrypt() returns correct promise, method Promise.resolve() can be skipped.

var promises = [];

$.each(formID.elements, function(key, working){

    var promise = Promise.resolve(encrypt(working.value))
        .then(function(encrypted_msg) {
            console.log("processing");
            working.value = encrypted_msg;
        });

    promises.push(promise);

});

Promise.all(promises).then(function(){
    console.log( 'after all encryptions!' );
});
var iterator = [];
for (var counter = 0; counter < formID.elements.length; counter++) {
    var working = formID.elements[counter];
    iterator.push(encrypt(working.value));
}

Promise.all(iterator)
.then(fumction(data){
    //Here you have all data
})

You can synchronize your operation like this way. By collecting all asynchronus value references and point to them when they have data.

In case your data is dependent.

function myfunction(previousValue){
    if(breaking Condition){
        return Promise.resolve();
    }
    return encrypt(working.value).then(function(encrypted_msg) {
        working.value = encrypted_msg;
        return myfunction(working);
    });
}

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