Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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);
like image 301
sjbuysse Avatar asked May 04 '17 10:05

sjbuysse


People also ask

How do you check if a variable is a Promise?

To check if a value is promise, check if the type of the value is an object and has a property named then of type function, e.g. typeof p === 'object' && typeof p. then === 'function' . If both conditions return true , the value is a promise.

Can we use Promise in for loop?

To use Javascript promises in a for loop, use async / await . This waits for each promiseAction to complete before continuing to the next iteration in the loop. In this guide, you learn how async/await works and how it solves the problem of using promises in for loops.

What are the 3 states of a JavaScript Promise?

A Promise is in one of these states: pending: initial state, neither fulfilled nor rejected. fulfilled: meaning that the operation was completed successfully. rejected: meaning that the operation failed.

Do Promises run on a separate thread?

As I mentioned before, JavaScript code is executed on a single thread. The callback that processes the response from your created Promises still runs on your single main thread. Promises do, however, allow you to spawn asynchronous tasks, such as file I/O or making an HTTP request which runs outside of your code.


2 Answers

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.

like image 162
jfriend00 Avatar answered Oct 20 '22 12:10

jfriend00


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 e.g. RxJS for more complex stuff.

like image 32
Rafal Pastuszak Avatar answered Oct 20 '22 11:10

Rafal Pastuszak