useStepQueue.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  2. import useState from "rc-util/es/hooks/useState";
  3. import * as React from 'react';
  4. import { STEP_ACTIVATED, STEP_ACTIVE, STEP_NONE, STEP_PREPARE, STEP_PREPARED, STEP_START } from "../interface";
  5. import useIsomorphicLayoutEffect from "./useIsomorphicLayoutEffect";
  6. import useNextFrame from "./useNextFrame";
  7. var FULL_STEP_QUEUE = [STEP_PREPARE, STEP_START, STEP_ACTIVE, STEP_ACTIVATED];
  8. var SIMPLE_STEP_QUEUE = [STEP_PREPARE, STEP_PREPARED];
  9. /** Skip current step */
  10. export var SkipStep = false;
  11. /** Current step should be update in */
  12. export var DoStep = true;
  13. export function isActive(step) {
  14. return step === STEP_ACTIVE || step === STEP_ACTIVATED;
  15. }
  16. export default (function (status, prepareOnly, callback) {
  17. var _useState = useState(STEP_NONE),
  18. _useState2 = _slicedToArray(_useState, 2),
  19. step = _useState2[0],
  20. setStep = _useState2[1];
  21. var _useNextFrame = useNextFrame(),
  22. _useNextFrame2 = _slicedToArray(_useNextFrame, 2),
  23. nextFrame = _useNextFrame2[0],
  24. cancelNextFrame = _useNextFrame2[1];
  25. function startQueue() {
  26. setStep(STEP_PREPARE, true);
  27. }
  28. var STEP_QUEUE = prepareOnly ? SIMPLE_STEP_QUEUE : FULL_STEP_QUEUE;
  29. useIsomorphicLayoutEffect(function () {
  30. if (step !== STEP_NONE && step !== STEP_ACTIVATED) {
  31. var index = STEP_QUEUE.indexOf(step);
  32. var nextStep = STEP_QUEUE[index + 1];
  33. var result = callback(step);
  34. if (result === SkipStep) {
  35. // Skip when no needed
  36. setStep(nextStep, true);
  37. } else if (nextStep) {
  38. // Do as frame for step update
  39. nextFrame(function (info) {
  40. function doNext() {
  41. // Skip since current queue is ood
  42. if (info.isCanceled()) return;
  43. setStep(nextStep, true);
  44. }
  45. if (result === true) {
  46. doNext();
  47. } else {
  48. // Only promise should be async
  49. Promise.resolve(result).then(doNext);
  50. }
  51. });
  52. }
  53. }
  54. }, [status, step]);
  55. React.useEffect(function () {
  56. return function () {
  57. cancelNextFrame();
  58. };
  59. }, []);
  60. return [startQueue, step];
  61. });