Evan Almloff 2 lat temu
rodzic
commit
d7f9a07f4e

+ 5 - 0
packages/core/src/arena.rs

@@ -111,6 +111,11 @@ impl VirtualDom {
         for hook in scope.hook_list.get_mut().drain(..) {
             drop(unsafe { BumpBox::from_raw(hook) });
         }
+
+        // Drop all the futures once the hooks are dropped
+        for task_id in scope.spawned_tasks.borrow_mut().drain() {
+            scope.tasks.remove(task_id);
+        }
     }
 
     fn drop_scope_inner(&mut self, node: &VNode) {

+ 7 - 1
packages/core/src/diff.rs

@@ -938,7 +938,13 @@ impl<'b> VirtualDom {
 
         // make sure to wipe any of its props and listeners
         self.ensure_drop_safety(scope);
-        self.scopes.remove(scope.0);
+        let scope_id = scope.0;
+        let scope = unsafe { self.scopes.get_unchecked_mut(scope.0) };
+        // Drop all the futures once the hooks are dropped
+        for task_id in scope.spawned_tasks.borrow_mut().drain() {
+            scope.tasks.remove(task_id);
+        }
+        self.scopes.remove(scope_id);
     }
 
     fn find_first_element(&self, node: &'b VNode<'b>) -> ElementId {

+ 5 - 1
packages/core/src/scopes.rs

@@ -319,7 +319,9 @@ impl<'src> ScopeState {
 
     /// Pushes the future onto the poll queue to be polled after the component renders.
     pub fn push_future(&self, fut: impl Future<Output = ()> + 'static) -> TaskId {
-        self.tasks.spawn(self.id, fut)
+        let id = self.tasks.spawn(self.id, fut);
+        self.spawned_tasks.borrow_mut().insert(id);
+        id
     }
 
     /// Spawns the future but does not return the [`TaskId`]
@@ -340,6 +342,8 @@ impl<'src> ScopeState {
             .unbounded_send(SchedulerMsg::TaskNotified(id))
             .expect("Scheduler should exist");
 
+        self.spawned_tasks.borrow_mut().insert(id);
+
         id
     }