gpt4 book ai didi

javascript - 我怎样才能正确地消除 firebase 云功能的执行

转载 作者:行者123 更新时间:2023-11-30 13:49:09 26 4
gpt4 key购买 nike

我有一个 Firebase 云函数,它根据 Firebase 的 documentation 中提供的示例监控对我的实时数据库的更改。 .

我的函数工作正常,并按照其编写的方式执行每次更改。

话虽如此,并且根据 Firebase 的建议:

• Debouncing - when listening to realtime changes in Cloud Firestore, this solution is likely to trigger multiple changes. If these changes trigger more events than you want, manually debounce the Cloud Firestore events.

我想这样做。

谁能提供一个好的方法?

如果我们根据 Firebase 的示例查看此函数:

exports.onUserStatusChanged = functions.database.ref('/status/{uid}').onUpdate(
async (change, context) => {

// Get the data written to Realtime Database
const eventStatus = change.after.val();

// Create a reference to the corresponding Firestore document
const userStatusFirestoreRef = firestore.doc(`status/${context.params.uid}`);

// re-read the current data and compare the timestamps.

const statusSnapshot = await change.after.ref.once('value');
const status = statusSnapshot.val();

// If the current timestamp for this data is newer than
// the data that triggered this event, we exit this function.

if (status.last_changed > eventStatus.last_changed) {
return null;
}

// Otherwise, we convert the last_changed field to a Date

eventStatus.last_changed = new Date(eventStatus.last_changed);

// write it to Firestore

userStatusFirestoreRef.get().then((user: any) => {
user.forEach((result: any) => {
result.ref.set(eventStatus, { merge: true })
});
});
return;
});

我应该如何尝试去抖动它的执行?

我可以尝试去抖动 .onUpdate() 事件吗?

我最初认为以下内容就足够了:

functions.database.ref('/status/{uid}').onUpdate(
debounce(async(change:any, context:any) => {
...
}, 10000, {
leading: true,
trailing: false
})
);

但是,感谢@doug-stevenson 指出,由于以下原因,尝试以这种方式消除 onUpdate 事件的抖动是行不通的:

“这是行不通的,因为函数的每次调用都可能发生在完全不同的没有共享上下文的服务器实例中。”

最佳答案

一种方法是使用任务调度程序(例如 Google Cloud Tasks)。您将使用任务调度程序来控制何时处理事件,而不是直接在云函数本身中处理事件。

我提供了两种方法:一种用于去抖,一种用于延迟 throttle 。

去抖动

这个想法是为每个云函数调用排队一个任务。如果已经为该实体安排了任务,则应取消现有任务。

例如,如果您的去抖间隔为 5 分钟,则将每个任务安排在未来 5 分钟后。安排好每个任务后,取消该实体的前一个任务(如果有的话)。当任务最终运行时,这意味着在 5 分钟内没有其他云调用(即成功去抖)。

延迟 throttle

延迟节流意味着您的事件在每个时间间隔最多处理一次,在时间间隔结束时。

想法是:每次云函数运行时,仅当任务不是重复时才将其入队。您需要想出一个任务命名约定,让您删除冗余任务。

例如,您可以将计划的执行时间附加到实体 ID。当您的云函数运行时,如果已经有针对该 ID 和时间的计划任务,您可以安全地忽略该事件。

这是一个每分钟最多处理一次事件的代码示例。

// round up to the nearest minute
const scheduleTimeUnixMinutes = Math.ceil(new Date().getTime() / 1000 / 60);
const taskName = id + scheduleTimeUnixMinutes.toString();
const taskPath = client.taskPath(project, location, queue, taskName);

// if there's already a task scheduled for the next minute, we have nothing
// to do. Google's client library throws an error if the task does not exist.
try {
await client.getTask({ name: taskPath });
return;
} catch (e) {
// NOT_FOUND === 5. If the error code is anything else, bail.
if (e.code !== 5) {
throw e;
}
}

// TODO: create task here

关于javascript - 我怎样才能正确地消除 firebase 云功能的执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58644361/

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