gpt4 book ai didi

javascript - Firebase 函数

转载 作者:行者123 更新时间:2023-12-02 23:56:05 24 4
gpt4 key购买 nike

我正在建立一个像游戏一样的网站。我现在想每 5 分钟更新一次用户的统计数据(金币等)。为此,我设置了一个每 5 分钟运行一次的 cronjob,没有问题。然而,Firebase 函数似乎可能“挂起”,即使在其网站上,它们持续了大约 5 毫秒。

我刚刚发现,如果我在 cronjob 运行(函数运行)时“购买”,我会发现“黄金”可能不会更新,它会立即设置回我开始购买时的状态。

  1. 我的函数可以接受吗?
  2. 卡在哪里?是因为我循环了(现在 100 个)假用户吗?
  3. 如果是这样,为什么 Firebase 会说主要需要 5 毫秒才能完成?
  4. 是否有任何方法可以确保,如果用户在函数将要安全时进行更新,函数就会更新最新值?
import * as functions from 'firebase-functions';

import * as admin from "firebase-admin";

import {UnitsDTO} from '../../ProjectXFrontend/src/ModelsDTO/Unit/unitsDTO';
import {CurrencyDTO} from '../../ProjectXFrontend/src/ModelsDTO/Currency/CurrencyDTO';

admin.initializeApp();

export const test = functions.https.onRequest((reques , respon) => {
admin.database().ref('/LastUpdated').set(
admin.database.ServerValue.TIMESTAMP
).then().catch()
return respon.send(reques.ip);
});

export const GetTime = functions.https.onRequest((request , response) => {
return response.send({data: new Date()})
});

export const CalculateBasics = functions.https.onRequest((request , res) => {
if (request.ip === '195.201.26.157') {
CalculateBreeder();
return res.send('ok');
} else {
res.statusCode = 400;
return res.send(new Error('Bad request'))
}

});

export const CalculateIncome = functions.https.onRequest((request , res) => {
if (request.ip === '195.201.26.157') {
CalculateIncomePrivate();
return res.send('ok');
} else {
res.statusCode = 400;
return res.send(new Error('Bad request'))
}
});




function CalculateIncomePrivate() {
admin.database().ref('/users').once('value').then( snap => {
snap.forEach( child => {
const user = child.key // uid
admin.database().ref('users/' + user).once('value').then(snapUser => {
const units = new UnitsDTO();
const currency = new CurrencyDTO();
if (snapUser.hasChild('Units')) { // in units
units.worker = snapUser.child('Units').child('worker').val()
}
if (snapUser.hasChild('currency/gold')) { // gold
currency.goldDto = snapUser.child('currency/gold').val();
}
// calculate news
currency.goldDto.amount += units.worker.amount * units.worker.currencyPerTick;

// set the Income
admin.database().ref('users/' + user + '/currency/gold').set(currency.goldDto).then().catch(error => {console.error(error)})
// update time
admin.database().ref('/status/LastIncome').set(
admin.database.ServerValue.TIMESTAMP
)
.then(() => {
// return res.send('ok');

})
.catch(error => {
// res.statusCode = 500;
// return res.send(error)

});

}).catch(error => {
// res.statusCode = 500;
// return res.send(error);
});
})
}).catch(error => {
// res.statusCode = 500;
// return res.send(error);
})
}


所以,预期的结果当然是该函数更新了用户的收入,它确实做到了,但是看起来它“挂起”并且更新得不太正确,因为用户在函数运行。

最佳答案

这是一个异步与阻塞问题。

CalculateIncomePrivate 是异步的,因此代码执行将前进到下一行,返回

所以将你的函数更改为

function  CalculateIncomePrivate()
return admin.database...

然后这样调用它:

exports.CalculateIncome....
return CalculateIncomePrivate().then(function(){
resp....
}).catch(function(error){
resp.status(500).send(error);
});

确保返回任何链式 promise 。

这应该可以帮助你兑现 promise https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Firebase Functions 的 promise https://www.youtube.com/playlist?list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM

关于javascript - Firebase 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55385777/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com