JavaScript中的while循环中条件为Promise

11

是否可能创建一个本地JavaScript while循环,其中条件是一个Promise?

编辑: 我要做的是在上传文件到Firebase存储之前实现一个检查,以查看Firebase存储中是否已存在具有相同名称的文件。如果已经存在具有相同名称的文件,则添加一个随机后缀并再次检查。

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);

1
你可能需要一种递归函数。请在代码中演示你的具体问题或需求。 - musefan
你能解释一下你想做什么吗?从技术上讲,你可以使用一个 Promise 作为条件来创建一个循环,但是循环会立即退出,因为在 Promise 返回之前它将为 false。并不是说你不能反转它,但请解释一下你需要什么? - Dellirium
1
一个 Promise 不是一个可观察对象。它将在某个时间被解决或拒绝。它不提供值的流。 - andreim
2个回答

19

是否可以用原生的JavaScript while循环,其中条件是一个Promise?

不行。

尝试这样做会遇到几个问题:

  1. 使用ES6标准的Promise,没有办法直接测试Promise的值。只有通过.then()访问最终解析的值。无法做while (p !== resolved)

  2. 即使您可以循环Promises的值,由于Javascript是事件驱动和单线程的,如果您循环了它,那么Promise的异步操作永远不会运行,也永远无法被解决。

相反,你只需使用:

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

如果您想在循环中执行更多操作,我们需要先查看实际代码才能更好地为您提供建议。


如果您想重复某些操作直到满足某个条件,那么只需将该操作放入函数中,在.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
});

编辑:使用ES7,你可以使用asyncawait。虽然它实际上不是一个while循环,但由于你根本不需要“轮询”异步值,因此它将消除需要使用while循环的必要性。


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

函数f()的内部执行将暂停,直到承诺解决或拒绝。请注意,f()的调用者不会被暂停。一旦执行await行,f()将立即返回一个承诺。该承诺本身将在f()的内部执行最终完成时解析和拒绝。


如何在重试之间设置一个延迟,以便使用set-timeout实现此功能? - Scott
@Scott - 请查看这里的延迟/重试工作原理:(https://stackoverflow.com/questions/57792389/native-js-promise-retry-wrapper/57793057#57793057)和(https://stackoverflow.com/questions/49522955/js-handle-multiple-sequential-failed-async-requests/49523085#49523085)。 - jfriend00
在你的例子中,似乎无论 next() 是被递归调用还是返回,next().then 都会在第一次执行后立即执行。 - mixophrygian

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接