简体   繁体   English

如何避免嵌套承诺?

[英]How to avoid nested promises?

I'm trying to write firebase function and I wonder if is any way to avoid nested promises in this JavaScript code? 我正在尝试编写firebase函数,我想知道是否有任何方法可以避免此JavaScript代码中的嵌套承诺?

exports.sendNotification=functions.database.ref('/notifications/{user_id}/{notification_id}').onWrite((change,context)=>{

const userId=context.params.user_id;
const notificationId=context.params.notification_id;

console.log('We have a notification to send to: ', userId);

if(!change.after.val()){
    return console.log('A notification has been deleted from database ',notificationId);
}
const fromUser=change.after.ref.root.child("/notifications/"+userId+"/"+notificationId).once('value');
return fromUser.then(fromUserResult=>{
    const fromUserID=fromUserResult.val().from;
    console.log('You have new notification from'+fromUserID);

    const userQuery=change.after.ref.root.child(`users/${fromUserID}/name`).once('value');
    const deviceToken=change.after.ref.root.child("/users/"+userId+"/device_token").once('value');

    return Promise.all([userQuery, deviceToken]).then(resut=>{

        const userName=resut[0].val();
        const token_id=resut[1].val();

        const payload={
            notification:{
                title: "Friend request",
                body: `${userName} has send you request`,
                icon: "default",
                click_action: "com.mwdevp.android.lapitchat_TARGET_NOTIFICATION"
            },
            data :{
                USER_KEY: fromUserID
            }
        };

        return admin.messaging().sendToDevice(token_id,payload).then(response=>{
        console.log('This was the notification feature');
        return;
        });

    });
});
});

Does somebody any idea how can I avoid nested promises in this code? 是否有人知道如何避免在此代码中嵌套诺言?

In ES7, you can wrap the entire code around an async function and use await : 在ES7中,您可以将整个代码包装在async函数周围,并使用await

async function f() {
  ...
  const fromUserResult = await change.after.ref.root.child(...);
  ...
  const resut = await Promise.all(...);
  const userName = resut[0].val();
  ...
}

f();

You will need to be on Node version >= 7 or use Babel . 您将需要使用节点版本> = 7或使用Babel

Move the nested then calls to the outer promise chain, and pass the variables you need in a next then callback as extra value in the Promise.all call: 将嵌套的then调用移至外部promise链,并在下一个then回调的过程中将所需的变量作为Promise.all调用中的额外值Promise.all

return fromUser.then(fromUserResult=>{
    const fromUserID=fromUserResult.val().from;
    console.log('You have new notification from'+fromUserID);

    const userQuery=change.after.ref.root.child(`users/${fromUserID}/name`).once('value');
    const deviceToken=change.after.ref.root.child("/users/"+userId+"/device_token").once('value');

    return Promise.all([userQuery, deviceToken, fromUserID]); // <--- add third value
}).then(resut=>{
    const userName=resut[0].val();
    const token_id=resut[1].val();

    const payload={
        notification:{
            title: "Friend request",
            body: `${userName} has send you request`,
            icon: "default",
            click_action: "com.mwdevp.android.lapitchat_TARGET_NOTIFICATION"
        },
        data :{
            USER_KEY: resut[2]; // <----
        }
    };

    return admin.messaging().sendToDevice(token_id,payload);
}).then(response=>{
    console.log('This was the notification feature');
    return;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM