问题
I'm trying to write firebase function and I wonder if is any way to avoid nested promises in this JavaScript code?
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?
回答1:
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:
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;
});
回答2:
In ES7, you can wrap the entire code around an async
function and use 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.
来源:https://stackoverflow.com/questions/50318627/how-to-avoid-nested-promises