任务:在main函数中,调用两个函数,第一个函数包含异步方法。
在ReadValueBalances函数中,once()方法返回Promise。然后我使用then()并返回结果。 在此之后,应该启动第二个函数UpdateValueMapBalances。
但是,为什么首先执行UpdateValueMapBalances而不是ReadValueBalances?
'use strict';
// The Cloud Functions for Firebase SDK to create Cloud Functions and setup triggers.
const FBfunctions = require('firebase-functions');
// The Firebase Admin SDK to access the Firebase Realtime Database.
const admin = require('firebase-admin');
admin.initializeApp();
exports.UpdateBalancesUser = FBfunctions.database.ref('/{userID}/Movements').onWrite((MoveDataChange, context) => {
const UserID = String(context.params.userID);
const BalanceRef = admin.database().ref('/'+ UserID +'/Balances') ;
var Date_first, Date_last;
var Value_first = 0;
var Value_last = 0;
var TypeofChange = 0;
MoveDataChange.after.forEach((childMove) => {
if (!childMove.exists()) {
console.log('MoveDataChange.after: нет!');
//return false; //выходим из функции
}
Date_last = childMove.child('dateInMilisec').val();
Value_last = childMove.child("value").val()*childMove.child("kind").val();
console.log('Date_last: ', Date_last, '. Value_last: ', Value_last);
TypeofChange = TypeofChange +1;
//return true;
});
MoveDataChange.before.forEach((childMove) => {
if (!childMove.exists()) {
console.log('MoveDataChange.before: нет!');
//return false; //выходим из функции
}
Date_first = childMove.child('dateInMilisec').val();
Value_first = -childMove.child("value").val()*childMove.child("kind").val(); //с обратным знаком, т.к. его не стало
console.log('Date_first: ', Date_first, '. Value_first: ', Value_first);
TypeofChange = TypeofChange - 1;
//return true;
});
console.log('TypeofChange: ', TypeofChange);
if (TypeofChange < 0) { // удалили движение
Date_last = Date_first;
Value_last = 0;
}
if (TypeofChange > 0) { // новое движение
Date_first = Date_last;
Value_first = Value_last;
Value_last = 0;
}
if (Date_first > Date_last) { //меняем местами
let Date_tmp = Date_first;
Date_first = Date_last;
Date_last = Date_tmp;
let Value_tmp = Value_first;
Value_first = Value_last;
Value_last = Value_tmp;
}
let BalanceMap = new Map;
let BalanceMapUpdate = new Map;
return ReadValueBalances(Date_first, BalanceRef)
.then(UpdateValueMapBalances(BalanceMap, Date_first, Date_last, Value_first, Value_last))
.then((BalanceMapUpdate)=>{
return BalanceRef.update(BalanceMapUpdate, ()=>{
console.log('Записали изменения ', BalanceMapUpdate);
})
});
});
function ReadValueBalances(Date_1, BalanceRef){
var BalancesMap = new Map;
return BalanceRef.orderByKey().startAt(String(Date_1)).once('value') // считываем значения БД после даты записи движения
.then((DataSnapShot)=>{
console.log('ReadValueBalances Получили выгрузку от ', Date_1);
if (!DataSnapShot.exists()) { // если после даты ничего, то считываем последнее значение до даты движения
console.log('ReadValueBalances Получаем последнюю запись');
return BalanceRef.orderByKey().endAt(String(Date_1)).limitToLast(1).once('value');
}
else {
console.log('ReadValueBalances Выгрузка есть');
return DataSnapShot;
}
})
.then((DataSnapShot)=>{
DataSnapShot.forEach((snapshot)=>{ // цикл по элементам выгрузки. записываем в Map
BalancesMap.set(snapshot.key, snapshot.val());
console.log('snap key: ', snapshot.key, ' value:', snapshot.val());
});
console.log('ReadValueBalances Закончили цикл');
return BalancesMap;
});
}
function UpdateValueMapBalances(BalanceMap_input, Date1, Date2, Delta1, Delta2){
var BalanceMap_output = new Map;
const Date_1 = new Date(Date1);
const Date_2 = new Date(Date2);
console.log('UpdateValueMapBalances Date_1: ', Date_1, ' Date_2: ', Date_2);
if (BalanceMap_input.size === 0) {
console.log('UpdateValueMapBalances вх.коллекция пустая');
var Date_item = new Date(Date_1);
console.log('UpdateValueMapBalances Date_item: ', Date_item);
Date_item.setDate(1);
Date_item.setMonth(Date_item.getMonth()+1);
BalanceMap_output.set(Date_item.getMilliseconds(), Delta1);
console.log('UpdateValueMapBalances BalanceMap_output: ', BalanceMap_output);
return BalanceMap_output;
}
BalanceMap_input.forEach((ValueItem, KeyItem, MapItem)=>{
console.log('ValueItem: ', ValueItem, ' KeyItem: ', KeyItem);
if (KeyItem <= Date1) { // возможно только в случае, если в выгрузке только 1 значение (до даты движения)
console.log('UpdateValueMapBalances Дополняем коллекцию сверху');
var bool_stop = false;
var Date_item = new Date(KeyItem);
Date_item.setDate(1); // на всякий случай
console.log('Date_item ', Date_item);
while (!bool_stop) {
Date_item.setMonth(Date_item.getMonth()+1);
if ((Date_item-Date_1) <= 0) {
BalanceMap_output.set(Date_item.getMilliseconds, ValueItem);
} else {
BalanceMap_output.set(Date_item.getMilliseconds, ValueItem + Delta1); // в случае с удалением delta 1= -Value
bool_stop = true;
}
}
console.log('UpdateValueMapBalances Дополнили коллекцию сверху');
return BalanceMap_output; //TODO: выйти из цикла
} else {
console.log('UpdateValueMapBalances Изменяем коллекцию снизу');
if (KeyItem <= Date2) { // т.е. коллекция имеет значения после Date_first до Date_last. Срабатывает только если даты отличаются
BalanceMap_output.set(KeyItem, ValueItem + Delta1);
} else { // т.е. коллекция имеет значения после Date_last
BalanceMap_output.set(KeyItem, ValueItem + Delta1 + Delta2); // в случае с новым движением/удалением Delta2=0, а Delta1= -Value
}
console.log('UpdateValueMapBalances Изменили коллекцию снизу');
}
})
return BalanceMap_output;
日志:
2:23:26.362 PM
outlined_flag
UpdateBalancesUser
Function execution took 1699 ms, finished with status: 'ok'
2:23:26.356 PM
info
UpdateBalancesUser
Записали изменения Map { '1522540800000' => 200000 }
2:23:26.353 PM
info
UpdateBalancesUser
ReadValueBalances Закончили цикл
2:23:26.353 PM
info
UpdateBalancesUser
snap key: 1522540800000 value: 200000
2:23:26.353 PM
info
UpdateBalancesUser
ReadValueBalances Выгрузка есть
2:23:26.352 PM
info
UpdateBalancesUser
ReadValueBalances Получили выгрузку от 1519862400000
2:23:25.861 PM
info
UpdateBalancesUser
UpdateValueMapBalances BalanceMap_output: Map { [Function: getMilliseconds] => -400000 }
2:23:25.860 PM
info
UpdateBalancesUser
UpdateValueMapBalances Date_item: 2018-03-01T00:00:00.000Z
2:23:25.860 PM
info
UpdateBalancesUser
UpdateValueMapBalances вх.коллекция пустая
2:23:25.860 PM
info
UpdateBalancesUser
UpdateValueMapBalances Date_1: 2018-03-01T00:00:00.000Z Date_2: 2018-03-01T00:00:00.000Z
2:23:25.849 PM
info
UpdateBalancesUser
TypeofChange: 0
2:23:25.849 PM
info
UpdateBalancesUser
Date_first: 1519862400000 . Value_first: -400000
答案 0 :(得分:1)
问题在于这一行
=sumproduct(A1:A8*0.1>=C2)
将其分解, .then(UpdateValueMapBalances(BalanceMap, Date_first, Date_last, Value_first, Value_last))
期望函数作为参数https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
但正在发生的事情是您直接调用then
并将其中的返回值用作UpdateValueMapBalances
的参数
这里用一种略微不同的方式来说明:
then
将该函数调用包装在另一个函数中将有望解决您的问题,假设您正确地通过参数传递所有正确的数据。这里有太多让我说的。
const successFunction = UpdateValueMapBalances(BalanceMap, Date_first, Date_last, Value_first, Value_last);
...
.then(successFunction)