1
0

suspense.rs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. use dioxus::prelude::*;
  2. use std::future::poll_fn;
  3. use std::task::Poll;
  4. #[test]
  5. fn suspense_resolves() {
  6. // wait just a moment, not enough time for the boundary to resolve
  7. tokio::runtime::Builder::new_current_thread()
  8. .build()
  9. .unwrap()
  10. .block_on(async {
  11. let mut dom = VirtualDom::new(app);
  12. dom.rebuild(&mut dioxus_core::NoOpMutations);
  13. dom.wait_for_suspense().await;
  14. let out = dioxus_ssr::render(&dom);
  15. assert_eq!(out, "<div>Waiting for... child</div>");
  16. dbg!(out);
  17. });
  18. }
  19. fn app() -> Element {
  20. rsx!(
  21. div {
  22. "Waiting for... "
  23. suspended_child {}
  24. }
  25. )
  26. }
  27. fn suspended_child() -> Element {
  28. let mut val = use_signal(|| 0);
  29. // Tasks that are not suspended should never be polled
  30. spawn(async move {
  31. panic!("Non-suspended task was polled");
  32. });
  33. // Memos should still work like normal
  34. let memo = use_memo(move || val * 2);
  35. assert_eq!(memo, val * 2);
  36. if val() < 3 {
  37. let task = spawn(async move {
  38. // Poll each task 3 times
  39. let mut count = 0;
  40. poll_fn(|cx| {
  41. println!("polling... {}", count);
  42. if count < 3 {
  43. count += 1;
  44. cx.waker().wake_by_ref();
  45. Poll::Pending
  46. } else {
  47. Poll::Ready(())
  48. }
  49. })
  50. .await;
  51. println!("waiting... {}", val);
  52. val += 1;
  53. });
  54. suspend(task)?;
  55. }
  56. rsx!("child")
  57. }