简体   繁体   中英

Javascript while loop where condition is a promise

Is it possible to make a native JavaScript while loop where the condition is a promise?

Edit: What I'm trying to do is implement a check before uploading a file to firebase storage, to see if a file with the same name already exists in the firebase storage. If there is already a file with the same name then add a random suffix and check again.

var storageRef = firebase.storage().ref().child(fileName);

while(storageRef.getDownloadURL()) {
    // create random number in between 0 and 100
    var random = Math.floor((Math.random() * 100) + 1);    
    storageRef = firebase.storage().ref().child(fileName + random);
}

storageRef.put(file);

Is it possible to make a native JavaScript while loop where the condition is a promise?

No, it is not.

There are a couple problems with trying to do that:

  1. With ES6 standard promises, there is no way to directly test the value of a promise. The only access to the eventually resolved value is with .then() . You can't do while (p !== resolved) .

  2. Even if you could loop on the promises value, because Javascript is event driven and single threaded, if you did do a loop, then the asynchronous operation of the promise could never run and the promise could never get resolved anyway.

Instead, you simply use:

p.then(function(result) {
    // process result here
}).catch(function(err) {
    // process error here
});

If there's more you wanted to do in your loop, you would have to disclose that actual code before we could advise further on how to best do that.


If you want to repeat some operation until some condition, then just put that operation in a function, test the condition in the .then() handler and if you want to repeat, then just call the function again.

function doSomething() {
    // some async operation that returns a promise
}

function next() {
    return doSomething.then(function(result) {
        if (result < someValue) {
             // run the operation again
             return next();
        } else {
             return result;
        }
    });
}

next().then(function(result) {
      // process final result here
}).catch(function(err) {
    // process error here
});

EDIT: With ES7, you can use async and await . It won't really be a while loop, but it will obviate the need for a while loop because you don't have to "poll" the asynchronous value at all.

async function f() {
   let value = await somePromise;
   // put code here to execute after the promise
   console.log(value);
}

The internal execution of function f() will be paused until the promise resolves or rejects. Note that the caller of f() will not be paused. f() will return a promise immediately as soon as the await line is executed. That promise itself will resolve and reject when the internal execution of f() finally finishes.

Yes it is!

What you're looking for are generators: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators .

I prefer using Observables eg RxJS for more complex stuff.

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