【发布时间】:2018-10-23 05:10:33
【问题描述】:
0) 我有一个 HTTP 触发器:
exports.checkout = functions.https.onRequest((req, res) => {
1) 用户购买充值包时更新充值交易:
admin.database().ref('topupTransaction').push(topUpObject)
2) 获取用户对象(有账户余额)
admin.database().ref('/users/' + userID).once("value",snap=> {
3) 设置新的用户对象(带有新的账户余额)
admin.database().ref('/users/' + req.query.userUid).set(topUpObject);
我不确定如何按顺序运行所有这些 (1,2,3) 并将值返回给客户端 (0)。击球不应该嵌入承诺。有 Promise.all,但是在这种情况下如何使用它。
点击“避免嵌套承诺”。当我尝试这样做时:
exports.checkout = functions.https.onRequest((req, res) => { var nonceFromTheClient = req.body.payment_method_nonce;
var topUpObject = {
amount : parseInt(req.query.topUpPackage),
date : admin.database.ServerValue.TIMESTAMP, // 1525451616097
user : req.query.userUid
};
admin.database().ref('topupTransaction').push(topUpObject)
.then((topUpResult) => {
return admin.database().ref('/users/' + userID).once("value");
}).then((oldUserData)=>{
return admin.database().ref('/users/' + req.query.userUid).set(topUpObject).then((newUserData)=>{
return res.send(newUserData.val());
})
;
}).catch((error) => {
// Update databse failed (top up transaction)
console.log('Error sending message:', error);
return res.status(500).send(error);
});
更新
使用 Promise.all,但部分工作出现错误:
// Create 2 functions
function asyncFunction1(topUpObject){
// Push top up object to database
admin.database().ref('topupTransaction').push(topUpObject)
.then((response) => {
// Update databse successful (top up transaction)
console.log('Top Up transaction created successfully!', topUpObject);
// return res.redirect(303, response.ref);
return topUpObject;
}).catch((error) => {
// Update databse failed (top up transaction)
console.log('Error sending message:', error);
return error;
});
}
function asyncFunction2(userID,topUpObject){
// Get the user account balance
console.log('Current User ID: ', userID);
var ref = admin.database().ref('users').child(userID);
admin.database().ref('/users/' + userID).once("value",snap=> {
// do some stuff once
console.log('Current User Data',snap.val());
console.log('Current User balance',snap.val().accountBalance);
var userContents = snap.val();
var currentBalance = userContents.accountBalance;
var updatedBalance = currentBalance + topUpObject.amount;
console.log('Updated Balance',updatedBalance);
userContents.accountBalance = updatedBalance;
/*Current User Data {
accountBalance: 0,
accountCurrency: 'MYR',
createdOn: '2018-05-02T20:42:49Z',
phoneNumber: '+123445555555'
}
*/
admin.database().ref('/users/' + userID).set(userContents).then(snapshot => {
console.log('Updated top up value! for user', topUpObject);
return res.send(topUpObject.amount);
}).catch((error) => {
// Update databse failed (top up transaction)
console.log('Error sending message:', error);
return error;
});
});
}
// app.post("/checkout", function (req, res) {
exports.checkout = functions.https.onRequest((req, res) => {
var nonceFromTheClient = req.body.payment_method_nonce;
// Use payment method nonce here
// Create Transaction
gateway.transaction.sale({
amount: req.query.topUpPackage,
paymentMethodNonce: nonceFromTheClient,
options: {
submitForSettlement: true
}
},(err, result) => { //TODO: What should we pass back here???
if (err) {
// If top up error (from braintree)
console.log(err.stack);
}else{
// If top up is successful
console.log('Result:',result);
console.log('Top Up Package is: ', req.query.topUpPackage);
var topUpObject = {
amount : parseInt(req.query.topUpPackage),
date : admin.database.ServerValue.TIMESTAMP, // 1525451616097
user : req.query.userUid
};
return Promise.all([asyncFunction1(topUpObject), asyncFunction2(req.query.userUid,topUpObject)]); //TODO: how to pass back res() to client???
}
// Return the error as response
return res.send(err);
});
});
exports.client_token = functions.https.onRequest((req, res) => {
// a token needs to be generated on each request
// so we nest this inside the request handler
// Need to write a function to return a client token,
// and return it back by using the res.send command
console.log('Log customerId',req.query.text);
gateway.clientToken.generate({
// customerId: req.query.text
}, (err, response) => {
// error handling for connection issues
if (err) {
console.log(err.stack);
}else{
clientToken = response.clientToken;
console.log('Log Client token:',clientToken);
return res.send(clientToken);
}
return res.send(err);
});
// return null;
});
【问题讨论】:
-
@Doug Stevenson,看过你的 YouTube 视频 youtube.com/watch?v=d9GrysWH1Lc。非常喜欢视频。您是否有任何视频更详细地解释了 Promise.all 返回值?
-
Promise.all 返回什么?
标签: node.js firebase google-cloud-functions firebase-admin