Я создаю простое приложение для Firebase.Основная текстовая область связана с записью в Firebase.Когда пользователь вводит, я debounce
событие keyup (300 мс) и обновляю Firebase.
Каждое событие .update
запускает событие onSnapshot
, когда оно возвращается с сервера (котороеожидаемое поведение Firebase).Моя проблема в том, что это мешает пользователю, пока он печатает.Потому что существует задержка между временем отправки запроса на сервер и его возвратом.Когда он возвращается, пользователь уже набрал больше текста, и содержимое текстовой области отличается от того, когда был запущен .update
.
Вот мой код и jsFiddle, который иллюстрирует проблему:
var textareaElement = document.querySelector('textarea');
// Initialize Firebase
var config = {
apiKey: "XXX",
authDomain: "XXX",
projectId: "XXX",
};
firebase.initializeApp(config);
const db = firebase.firestore();
const doc = db.collection("notes").doc('XXX');
// This is debounced
const update = function(){
doc.update({
text: textareaElement.value,
updated_at: firebase.firestore.FieldValue.serverTimestamp()
})
}
// Update the server when we change the client
textareaElement.addEventListener('keyup', _.debounce(update, 300));
// Listen for changes from the server
doc.onSnapshot(function(doc){
textareaElement.value = doc.data().text
});
jsFiddle
https://jsfiddle.net/x6h80keb/2 (введите в обычном темпе, и вы поймете, что я имею в виду)
jsFiddle - без serverTimestamp ()
https://jsfiddle.net/x6h80keb/6/
Я обнаружил, что удаление вызова функции serverTimestamp()
очень помогает.Похоже, он отвечает за задержку запроса.Это делает «ошибку» практически незаметной, но иногда это происходит, когда выполнение запроса занимает немного больше времени.
Единственное решение, о котором я могу подумать, - это обнаружить инициатора обновления.Всякий раз, когда срабатывает событие onSnapshot
, мы можем посмотреть на объект doc
и сказать, было ли изменение сделано с этого клиента или с другого.Но, по-видимому, такой функции не существует.
Есть идеи, как мне решить эту проблему?
РЕДАКТИРОВАТЬ:
В итоге я увеличил задержку отката.Вместо обновления через 300 мс я жду несколько секунд.Таким образом, пользовательский ввод не может быть нарушен.Я также замораживаю текстовую область во время обновления.