Node.js NodeJS Promise Firebase

Node.js NodeJS Promise Firebase,node.js,firebase,firebase-realtime-database,promise,google-cloud-functions,Node.js,Firebase,Firebase Realtime Database,Promise,Google Cloud Functions,爱上了nodeJS和异步自然!有了这些,我目瞪口呆地想知道如何继续bc我不能遵守嵌套承诺,当然这是不可能的,所以我举手bc每一步都需要一个完整的操作和上一步的数据 这就是我试图完成的,下面是代码 新学院成立了 在得到那把钥匙的价值后,去找订阅那所大学的顾问 为订阅顾问获取FCM代币 显然,我还没有谈到这一部分,但向订阅者发送FCM通知 塔达 你在正确的轨道上once()返回一个承诺,它是从重复调用到once的一组承诺,必须收集这些承诺并使用promise.all()运行 编辑再次编辑,这一次是

爱上了nodeJS和异步自然!有了这些,我目瞪口呆地想知道如何继续bc我不能遵守嵌套承诺,当然这是不可能的,所以我举手bc每一步都需要一个完整的操作和上一步的数据

这就是我试图完成的,下面是代码

  • 新学院成立了
  • 在得到那把钥匙的价值后,去找订阅那所大学的顾问
  • 为订阅顾问获取FCM代币
  • 显然,我还没有谈到这一部分,但向订阅者发送FCM通知
  • 塔达


    你在正确的轨道上
    once()
    返回一个承诺,它是从重复调用到once的一组承诺,必须收集这些承诺并使用
    promise.all()
    运行

    编辑再次编辑,这一次是在手头有OP的答案的情况下。关于样式,我不确定lint说了什么,但我对不良嵌套样式的定义是当一个
    then()
    块包含另一个
    then()
    块时。同样关于风格,我让这些东西易于理解的方法是构建(和测试)小函数,每个异步任务一个

    在结构上,OP的新答案不必要地将
    return advisors
    后的第二个块链接起来。由于advisors不是一个承诺,因此我们可以使用同步代码从那里继续。同样在结构上,OP的解决方案创建了一系列承诺——每个顾问两个承诺(获取顾问令牌和推送)——但除非应用并返回Promise.all,否则这些承诺不一定会完成

    综上所述,我的建议如下

    在创建时,请学院的顾问向每个人发送一条消息

    exports.newSessionNotifer = functions.database.ref('/sessions/{sessionID}/college').onCreate((snap, context) => {
        const college = snap.val(); 
        return advisorsForCollege(college).then(advisors => {
            let promises = advisors.map(advisor => sendAdvisorMessage(advisor, college));
            return Promise.all(promises);
        });
    });
    
    一所大学的顾问显然是该大学目标的关键

    function advisorsForCollege(college) {
        return admin.database().ref('colleges').child(college).once('value').then(snapshot => Object.keys(snapshot.val()));
    }
    
    发送顾问消息意味着获取顾问令牌并进行推送。返回这样做的两个承诺链

    function sendAdvisorMessage(advisor, college) {
        return tokenForAdvisor(advisor).then(token => {
            let title = `There's a new session for ${college}!`;
            let body = 'Go to the middle tab and swipe right to accept the session before your peers do!'
            return sendToDevice(token, title, body);
        });
    }
    
    现在我们只需要一个获得顾问的代币和一个做推

    function tokenForAdvisor(advisor) {
        return admin.database().ref('users').child(advisor).child('fcmtoken').child('token').once('value');
    }
    
    function sendToDevice(token, title, body) {
        const payload = { notification: { title: title, body: body } };
        return admin.messaging().sendToDevice(token, payload);
    };
    

    我认为lint应该报告上述所有内容,即使启用了promise nesting警告。

    您的思路是正确的
    once()
    返回一个承诺,它是从重复调用到once的一组承诺,必须收集这些承诺并使用
    promise.all()
    运行

    编辑再次编辑,这一次是在手头有OP的答案的情况下。关于样式,我不确定lint说了什么,但我对不良嵌套样式的定义是当一个
    then()
    块包含另一个
    then()
    块时。同样关于风格,我让这些东西易于理解的方法是构建(和测试)小函数,每个异步任务一个

    在结构上,OP的新答案不必要地将
    return advisors
    后的第二个块链接起来。由于advisors不是一个承诺,因此我们可以使用同步代码从那里继续。同样在结构上,OP的解决方案创建了一系列承诺——每个顾问两个承诺(获取顾问令牌和推送)——但除非应用并返回Promise.all,否则这些承诺不一定会完成

    综上所述,我的建议如下

    在创建时,请学院的顾问向每个人发送一条消息

    exports.newSessionNotifer = functions.database.ref('/sessions/{sessionID}/college').onCreate((snap, context) => {
        const college = snap.val(); 
        return advisorsForCollege(college).then(advisors => {
            let promises = advisors.map(advisor => sendAdvisorMessage(advisor, college));
            return Promise.all(promises);
        });
    });
    
    一所大学的顾问显然是该大学目标的关键

    function advisorsForCollege(college) {
        return admin.database().ref('colleges').child(college).once('value').then(snapshot => Object.keys(snapshot.val()));
    }
    
    发送顾问消息意味着获取顾问令牌并进行推送。返回这样做的两个承诺链

    function sendAdvisorMessage(advisor, college) {
        return tokenForAdvisor(advisor).then(token => {
            let title = `There's a new session for ${college}!`;
            let body = 'Go to the middle tab and swipe right to accept the session before your peers do!'
            return sendToDevice(token, title, body);
        });
    }
    
    现在我们只需要一个获得顾问的代币和一个做推

    function tokenForAdvisor(advisor) {
        return admin.database().ref('users').child(advisor).child('fcmtoken').child('token').once('value');
    }
    
    function sendToDevice(token, title, body) {
        const payload = { notification: { title: title, body: body } };
        return admin.messaging().sendToDevice(token, payload);
    };
    

    我认为lint应该报告上述所有内容,即使启用了promise nesting warning。

    多亏了danh,这是我的最终代码。远离评论/反馈!我决定在lint和viola中禁用promise嵌套选项

    exports.newSessionNotifer = functions.database.ref('/sessions/{sessionID}/college').onCreate((snap, context) => {
    const college = snap.val(); 
    return admin.database().ref('colleges').child(college).once('value').then((snapshot) => {
        const people = snapshot.val();  
        let advisors = Object.keys(people);
        return advisors;
    }).then((advisors) => {
        return advisors.map(advisor => {
                return admin.database().ref('users').child(advisor).child('fcmtoken').child('token').once('value').then((snapshot) => {
                const token = snapshot.val();
                const payload = {
                        notification: {
                        title: `There's a new session for ${college}!`,
                        body: 'Go to the middle tab and swipe right to accept the session before your peers do!'
                        }
                };
                return admin.messaging().sendToDevice(token, payload);
            });
        });
    });
    });
    

    多亏了danh,这是我的最终代码。远离评论/反馈!我决定在lint和viola中禁用promise嵌套选项

    exports.newSessionNotifer = functions.database.ref('/sessions/{sessionID}/college').onCreate((snap, context) => {
    const college = snap.val(); 
    return admin.database().ref('colleges').child(college).once('value').then((snapshot) => {
        const people = snapshot.val();  
        let advisors = Object.keys(people);
        return advisors;
    }).then((advisors) => {
        return advisors.map(advisor => {
                return admin.database().ref('users').child(advisor).child('fcmtoken').child('token').once('value').then((snapshot) => {
                const token = snapshot.val();
                const payload = {
                        notification: {
                        title: `There's a new session for ${college}!`,
                        body: 'Go to the middle tab and swipe right to accept the session before your peers do!'
                        }
                };
                return admin.messaging().sendToDevice(token, payload);
            });
        });
    });
    });
    

    你打算用这个
    数组做什么?如果
    advisors
    不是数组而是firebase快照,请先将其转换为数组。advisors“可以”是数组,因此我想通过执行forEach来适应它作为数组的可能性。重点(如链接中所述)是,不能将
    forEach
    与执行异步操作的回调一起使用。使用
    map
    创建承诺数组。
    我不能一直嵌套承诺
    -问题是,你没有嵌套承诺-如果你真的想要“扁平”代码
    async
    /
    等待救援
    您打算如何处理该阵列?如果
    advisors
    不是数组而是firebase快照,请先将其转换为数组。advisors“可以”是数组,因此我想通过执行forEach来适应它作为数组的可能性。重点(如链接中所述)是,不能将
    forEach
    与执行异步操作的回调一起使用。使用
    map
    创建承诺数组。
    我不能一直嵌套承诺
    -问题是,你没有嵌套承诺-如果你真的想要“扁平”代码
    async
    /
    Wait
    等待救援我不认为onCreate
    会返回一个承诺,是吗?@Bergi:每个需要在关闭
    }
    后继续运行的云函数都需要返回一个承诺。否则,云函数不知道该函数仍处于活动状态,可能会关闭/重用其容器。请参阅
    onCreate
    返回承诺的示例:@FrankvanPuffelen好的,我仍然理解OP的代码,因此他希望他的承诺链位于
    onCreate
    callback中。我更希望承诺链位于onCreate回调bc中,操作与该函数特别相关。@Ben,很抱歉我帮不了你。我不明白你对筑巢的定义。也许可以把它加到你的问题上