简体   繁体   English

Javascript while循环,其中条件是一个承诺

[英]Javascript while loop where condition is a promise

Is it possible to make a native JavaScript while loop where the condition is a promise? 是否有可能使一个原生的JavaScript while循环中条件承诺?

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. 编辑:我要做的是在将文件上传到firebase存储之前执行检查,以查看firebase存储中是否已存在具有相同名称的文件。 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? 是否可以在条件为承诺的情况下制作原生JavaScript?

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. 有了ES6标准承诺,就无法直接测试承诺的价值。 The only access to the eventually resolved value is with .then() . 对最终解析值的唯一访问是使用.then() You can't do while (p !== resolved) . 你做不到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. 即使你可以循环使用promises值,因为Javascript是事件驱动的和单线程的,如果你做了一个循环,那么promise的异步操作永远不会运行,并且承诺永远不会得到解决。

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. 如果你想在某些条件下重复某些操作,那么只需将该操作放入函数中,在.then()处理程序中测试条件,如果要重复,则再次调用该函数。

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 . 编辑:使用ES7,您可以使用asyncawait 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. 它实际上不是一个while循环,但它将消除对while循环的需要,因为你根本不必“轮询”异步值。

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. 函数f()的内部执行将暂停,直到promise解析或拒绝。 Note that the caller of f() will not be paused. 请注意, f()的调用者不会被暂停。 f() will return a promise immediately as soon as the await line is executed. 一旦执行await行, f()将立即返回一个promise。 That promise itself will resolve and reject when the internal execution of f() finally finishes. f()的内部执行最终完成时,该承诺本身将解决并拒绝。

Yes it is! 是的!

What you're looking for are generators: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators . 您正在寻找的是生成器: https//developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators

I prefer using Observables eg RxJS for more complex stuff. 我更喜欢使用Observables, 例如RxJS来处理更复杂的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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