【问题标题】:Keep variable between promises in a function?在函数中的承诺之间保持变量?
【发布时间】:2020-02-12 23:43:37
【问题描述】:

在 firebase 功能上,我需要从 Paypal 获取数据并做 4 件事:

1. returns an empty HTTP 200 to them.
2. send the complete message back to PayPal using `HTTPS POST`.
3. get back "VERIFIED" message from Paypal.
4. *** write something to my Firebase database only here.

我现在所做的有效,但我遇到了 (4) 的问题。

   exports.contentServer = functions.https.onRequest((request, response) => {
....

                       let options = {
                          method: 'POST',
                          uri: "https://ipnpb.sandbox.paypal.com/cgi-bin/webscr",
                          body: verificationBody
                           };

                           // ** say 200 to paypal
                           response.status(200).end();

                           // ** send POST to paypal back using npm request-promise
                           return rp(options).then(body => {

                            if (body === "VERIFIED") {

                              //*** problem is here!
                                   return admin.firestore().collection('Users').add({request.body}).then(writeResult => {return console.log("Request completed");});
                                }
                                return console.log("Request completed");
                              })
                              .catch(error => {
                                      return console.log(error);
                              })

正如您所见,当我从 Paypal 获得最终 VERIFIED 时,我尝试使用 admin.firestore().collection('Users').. 写入数据库

我在编译时收到警告:

Avoid nesting promises 

write 行。

在承诺的那个阶段我应该如何以及在哪里放置这个write

【问题讨论】:

    标签: node.js firebase google-cloud-functions


    【解决方案1】:

    我了解此 HTTPS 云函数是从 Paypal 调用的。

    通过在 HTTP 云函数的开头执行 response.status(200).end();您将终止它,如 doc 中所述:

    重要提示:确保所有 HTTP 函数都正确终止。经过 正确终止功能,您可以避免过度收费 运行时间过长的函数。终止 HTTP 函数 res.redirect()res.send()res.end()

    这意味着在大多数情况下,其余代码根本不会执行,或者函数将在异步工作的中间终止(即rp()add() 方法)

    您应该仅在所有异步工作完成后才将响应发送给调用者。以下应该有效:

    exports.contentServer = functions.https.onRequest((request, response) => {
    
        let options = {
            method: 'POST',
            uri: "https://ipnpb.sandbox.paypal.com/cgi-bin/webscr",
            body: verificationBody
        };
    
        // ** send POST to paypal back using npm request-promise
        return rp(options)
            .then(body => {
    
                if (body === "VERIFIED") {
                    //*** problem is here!
                    return admin.firestore().collection('Users').add({ body: request.body });
                } else {
                    console.log("Body is not verified");
                    throw new Error("Body is not verified");
                }
    
            })
            .then(docReference => {
                console.log("Request completed");
                response.send({ result: 'ok' }); //Or any other object, or empty
            })
            .catch(error => {
                console.log(error);
                response.status(500).send(error);
            });
    
    
    });
    

    我建议您观看 Doug Stevenson (https://firebase.google.com/docs/functions/video-series/) 关于云函数的官方视频系列,尤其是关于 Promises 的第一个视频,标题为“Learn JavaScript Promises (Pt.1) with HTTP Triggers in Cloud Functions”。

    【讨论】:

    • 对不起,我就是不明白。 (谢谢,很抱歉很苛刻)。我在这里到处读到 .end 只是完成了 RESONSE 而不是功能。此外,人们到处都在说这个(它终止了函数),并且在对这个特定代码的 100 次调用中,0(!)次它被终止并且所有其他代码都完美执行。那么 - 这里的真相是什么? Firebase 的另一个人在这里写道“响应只是完成请求,并且该功能肯定会保持活动状态” - 这似乎是正确的,因为我已经尝试了大约 500 次。
    • 除此之外-我无法按照您的建议更改事物的顺序。正如我所说 - 贝宝要求先发送 200 OK,然后再发送另一条消息。所以你改变了我的需求顺序,我做不到。 (再次,但非常感谢)。
    • 抱歉再发表评论 - 确实看过 Doug Stevenson 的所有视频,并且必须说(作为工程师)这些功能确实很混乱,人们对终止不不符合现实。 (我们的函数在响应/结束/返回后从未​​终止,其余代码始终执行。
    • 你去 - (抱歉无法编辑我的 cmets)这个人被高度投票并在答案中准确地说出这一点。 stackoverflow.com/questions/16180502/… - “当然结束了 HTTP 响应,但它不会对你的代码做任何特别的事情。”
    • 好吧,如果我可以这样说的话,事情不是“非黑即白”。正如文档中通过发送响应(res.redirect()res.send()res.end())解释的那样表示您终止 HTTP 函数。 AFAIK 这并不意味着无服务器系统将立即杀死云功能,而是告知它可以这样做。根据我们完全无法控制的几个元素,系统有时可能会决定让它继续运行并在以后终止它,但不能保证这一点。
    猜你喜欢
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 2016-09-18
    • 1970-01-01
    • 2018-05-09
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    相关资源
    最近更新 更多