У меня есть асинхронная функция, которая выполняет различные задачи ожидания. Я пытаюсь сообщить своему пользовательскому интерфейсу в React, когда состояние функции изменяется или когда одна из задач завершена.
const foo = async () => {
// trigger on load event
await task1();
// trigger task1 done event
await task2();
// trigger task2 done event
await task3();
// trigger on done event
}
Я также хочу иметь возможность указывать обратные вызовы для каждого события, например, так:
const bar = foo();
foo.on_load(() => {
// some code goes here
});
foo.on_done(() => {
// some code goes here
});
Другой альтернативой может быть что-то вроде этого:
const bar = foo();
foo.on('status_change', status => {
// read the status here and do something depending on the status
})
Я читал о пользовательских событиях в JS, но не уверен, как их использовать для этого. Или, может быть, есть другой способ сделать это в React.
Любые идеи будут полезны. Спасибо!
РЕДАКТИРОВАТЬ
var uploadTask = storageRef.child('images/rivers.jpg').put(file);
// Register three observers:
// 1. 'state_changed' observer, called any time the state changes
// 2. Error observer, called on failure
// 3. Completion observer, called on successful completion
uploadTask.on('state_changed', function(snapshot){
// Observe state change events such as progress, pause, and resume
// Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log('Upload is ' + progress + '% done');
switch (snapshot.state) {
case firebase.storage.TaskState.PAUSED: // or 'paused'
console.log('Upload is paused');
break;
case firebase.storage.TaskState.RUNNING: // or 'running'
console.log('Upload is running');
break;
}
}, function(error) {
// Handle unsuccessful uploads
}, function() {
// Handle successful uploads on complete
// For instance, get the download URL: https://firebasestorage.googleapis.com/...
uploadTask.snapshot.ref.getDownloadURL().then(function(downloadURL) {
console.log('File available at', downloadURL);
});
});
Я пытался добиться чего-то вроде приведенного выше кода, взятого из документации Firebase по загрузке файлов
Вот где я дошел до этого:
class Task {
constructor() {
this.first = null;
this.second = null;
}
on(keyword, callback) {
switch (keyword) {
case "first":
this.first = callback;
break;
case "second":
this.second = callback;
break;
default:
// throw new error
break;
}
}
}
const timeout = async time => {
return new Promise(resolve => setTimeout(resolve, time));
};
const foo = () => {
const task = new Task();
timeout(2000).then(async () => {
task.first && task.first();
await timeout(2000);
task.second && task.second();
});
console.log("returning");
return task;
};
const taskObject = foo();
taskObject.on("first", () => console.log("executing first callback"));
taskObject.on("second", () => console.log("executing second callback"));
Есть ли лучший способ сделать это - без вложенных потомков? Какой подход будет лучше и когда? EDIT - удалены вложенные пункты then
и заменены на then
и await
PS: для моих требований было бы достаточно иметь обратные вызовы. Это просто, чтобы я мог лучше понять концепцию. Спасибо!