【问题标题】:Firebase cloud function: problem with Promise.all(promise)Firebase 云功能:Promise.all(promise) 的问题
【发布时间】:2019-05-16 17:56:23
【问题描述】:

我在 Firebase 存储中循环抛出一个文件列表,我想在循环时修改一个字符串,

这是我尝试做的:

 var str;

 storage.bucket().file(...).download((err, content) => {
    str=content.toString();

    storage.bucket().getFiles(...).then(results => {
        const files = results[0];
        var promise = new Promise(function(resolve,reject){
           files.forEach(file => {
               ...
               str=str.replace("t","a");
           });
           resolve(str);
      });

      Promise.all(promise).then(function(str) {
        console.log(str); //NOT OKAY, the value is still "test" 

        file.save(str, function(err) { ... });
     });

我也试过了:

promise.then(function(result) {

但结果是一样的:(

更新: 我编辑了上面的代码,但它仍然不起作用:

有什么想法吗?

更新 2:

还是不行:(

【问题讨论】:

  • 请编辑问题以完整显示代码。你现在展示它的方式,不能保证你在第一个代码块中创建的承诺与你传递给 Promise.all() 的承诺是一样的。它可能超出范围。
  • 如果你在内部做异步操作,不要使用forEach。如果你不做异步操作,不要使用 Promise。
  • 你为什么使用Promise.all?你没有多个承诺,是吗?
  • 您的promise 变量是在then 回调内部创建的,您不能在外部使用它。但是then 已经为回调的返回值创建了一个承诺,就使用它吧!
  • @Bergi 那么用什么来代替 Promise.all 呢?或者没有forEach怎么办?我有点失落..

标签: javascript firebase promise


【解决方案1】:

如果它对某人有用,这是我找到的解决方案:

var promises = [];
var str="string containing data to replace with signed url";

storage.bucket().getFiles({ prefix: folderPath }).then(results => {
  const files = results[0];
  files.forEach(function(file) {

     promises.push( //the trick was here

       file.getSignedUrl(signedUrlConfig).then(signedUrls => {
         ...
         surl = signedUrls[0];
         str=str.replace("a",surl); //eg: replace with signed url.
         return str;
       });
     );
  });
  Promise.all(promises).then(() => {
    console.log(str); //str contains all signed url
  });
});

【讨论】:

  • WTH?您的问题中的代码中没有 file.getSignedUrl(signedUrlConfig) promise 调用,我们不可能想出这个解决方案。
  • 我写了"that直接去promise.then结果是"undefined":那只能表示sthg之前没有时间执行,所以我们可以猜到sthg是异步的即使没有编写异步代码,这就是我想出解决方案的方式。
【解决方案2】:

看来你在找

const promise = storage.bucket().file().download().then(str => {
//    ^^^^^^^^^                                   ^^^^^
    return storage.bucket().getFiles().then(results => {
//  ^^^^^^
        const files = results[0];
        for (const file of files) {
            …
            str = str.replace("t","a");
        }
        return str;
    //  ^^^^^^
    });
});

promise.then(str => { /*
^^^^^^^^^^^^ */
    console.log(str);
    return file.save(str); // should return a promise
});

这里不需要new PromisePromise.all。您可以使用后者来删除嵌套,甚至可能同时运行getFiles()download(),请参阅How do I access previous promise results in a .then() chain?

【讨论】:

  • async/await 通常也是一个不错的选择。 Firebase 函数需要(并且支持)Node 8 运行时。 Promise.all 最适合并行操作。
猜你喜欢
  • 1970-01-01
  • 2019-09-06
  • 1970-01-01
  • 2021-06-21
  • 1970-01-01
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多