【问题标题】:in firebase cloud function the bucket.upload promise resolves too early在 Firebase 云功能中,bucket.upload 承诺过早解决
【发布时间】:2017-12-13 21:29:32
【问题描述】:

我写了一个像这样工作的函数

onNewZipFileRequested
{get all the necessary data}
.then{download all the files}
.then{create a zipfile with all those file}
.then{upload that zipfile} (*here is the problem)
.than{update the database  with the signedUrl of the file}

这里是相关代码

[***CREATION OF ZIP FILE WORKING****]
}).then(() =>{
    zip.generateNodeStream({type:'nodebuffer',streamFiles:true})
    .pipe(fs.createWriteStream(tempPath))
    .on('finish', function () {
        console.log("zip written.");
        return bucket.upload(tempPath, {    //**** problem****
            destination: destinazionePath
        });
    });
}).then(()=>{
    const config = {
        action:'read',
        expires:'03-09-2391'
    }
    return bucket.file(destinazionePath).getSignedUrl(config)
}).then(risultato=>{
    const daSalvare ={
        signedUrl: risultato[0],
        status : 'fatto',
        dataInserimento : zipball.dataInserimento
    }
    return event.data.ref.set(daSalvare)
})

在客户端,只要应用看到状态变化和新的 URL,就会出现一个下载按钮(指向新的 URL)

一切正常,但如果我尝试立即下载文件...还没有文件!!!

如果我在同一时间重试,文件就在那里。

我注意到我必须等待的时间取决于压缩文件的大小。

bucket.upload 承诺应该在上传结束时解决,但显然触发得太早了。 有没有办法准确知道文件何时准备就绪? 我可能需要制作同样非常大的文件,如果这个过程需要几分钟,这不是问题,但我需要知道它什么时候结束。

* 编辑 *

代码中有不必要的嵌套。虽然这不是错误(重构前后的结果相同),但它导致答案有些混乱,所以我将其编辑了。

我想指出我只有在获得签名的 url 后才更新数据库,而且我只有在上传后才得到它(否则我不能),所以要在所有承诺链上获得任何结果必须工作,并且事实上确实如此。当在客户端出现下载按钮时(当'status'变为'fatto'时发生)它已经链接到正确的签名网址,但如果我过早按下它,文件不存在(失败 - 无文件)。如果我等待一秒钟(文件越大,我必须等待的时间越长),那么文件就在那里。

(英语不是我的母语,如果我不清楚,请询问,我会尝试更好地解释自己)

【问题讨论】:

  • 我很困惑——看起来你在一个 then() 块中有两个 return 语句。也许尝试减少嵌套量 - 我认为您没有理由将 then() 放在另一个 then() 中。它们都可以依次跟随。

标签: node.js firebase firebase-storage es6-promise google-cloud-functions


【解决方案1】:

看起来问题可能是大括号没有正确对齐,导致then 语句嵌入到另一个语句中。这是分隔then 语句的代码:

[***CREATION OF ZIP FILE WORKING****]}).then(() => {
    zip.generateNodeStream({type: 'nodebuffer', streamFiles: true})
    .pipe(fs.createWriteStream(tempPath))
    .on('finish', function () {
        console.log('zip written.')
        return bucket.upload(tempPath, { 
            destination: destinazionePath
        })
    })
}).then(() => {
    const config = {
        action: 'read',
        expires: '03-09-2391'
    }
    return bucket.file(destinazionePath).getSignedUrl(config)
}).then(risultato => {
        const daSalvare = {
            signedUrl: risultato[0],
            status : 'fatto',
            dataInserimento : zipball.dataInserimento
    }
    return event.data.ref.set(daSalvare)
})

【讨论】:

  • 谢谢,但没有。我可以而且也许应该避免这种嵌套(坏习惯),但这不会影响函数的结果。事实上,我刚刚尝试了您的代码,结果与预期完全相同:一切正常,但上传承诺解决得太早。这并不奇怪,因为您建议的重构发生在有问题的承诺之后......
猜你喜欢
  • 2023-04-01
  • 2018-04-19
  • 1970-01-01
  • 2019-07-14
  • 1970-01-01
  • 2019-06-15
  • 1970-01-01
  • 2020-03-21
  • 1970-01-01
相关资源
最近更新 更多