zoukankan      html  css  js  c++  java
  • [XState] Invoke with callback

    Invoke not only able to return a promise, but also a callback function with 'sendBack' & 'receive' callbacks

          invoke: {
            // nested state with id reference
            id: "child",
            // return a callback function
            src: (context, event) => (sendBack, receive) => {
              setTimeout(() => {
                // send out a event
                sendBack({
                  type: "I_AM_DONE",
                });
              }, 5000);
               // wait for receiving a event
              receive((event) => {
                console.log("event", event);
                if (event.type === "SNED_IT_ALREADY") {
                  sendBack({
                    type: "I_AM_DONE",
                  });
                }
              });
            },

    Receive a event:

          on: {
            RESOLVE: "resolved",
            // cancel the promise
            CANCEL: "idle",
            I_AM_DONE: "resolved",
            SNED_IT_ALREADY: {
              actions: send(
                {
                  type: "SNED_IT_ALREADY",
                },
                {
                  to: "child",
                }
              ),
            },
          },

    --- Full code---

    import { createMachine, assign, interpret, send } from "xstate";
    
    const elBox = document.querySelector("#box");
    
    const randomFetch = () => {
      return new Promise((res, rej) => {
        setTimeout(() => {
          if (Math.random() < 0.5) {
            rej("Fetch failed!");
          } else {
            res("Fetch succeeded!");
          }
        }, 2000);
      });
    };
    
    const machine = createMachine({
      initial: "idle",
      states: {
        idle: {
          on: {
            FETCH: "pending",
          },
        },
        pending: {
          on: {
            RESOLVE: "resolved",
            // cancel the promise
            CANCEL: "idle",
            I_AM_DONE: "resolved",
            SNED_IT_ALREADY: {
              actions: send(
                {
                  type: "SNED_IT_ALREADY",
                },
                {
                  to: "child",
                }
              ),
            },
          },
          invoke: {
            // Invoke your promise here.
            // The `src` should be a function that returns the source.
            /* Promise
            src: (context, event) => {
              return randomFetch();
            },
            */
            id: "child",
            src: (context, event) => (sendBack, receive) => {
              setTimeout(() => {
                sendBack({
                  type: "I_AM_DONE",
                });
              }, 5000);
    
              receive((event) => {
                console.log("event", event);
                if (event.type === "SNED_IT_ALREADY") {
                  sendBack({
                    type: "I_AM_DONE",
                  });
                }
              });
            },
            onDone: {
              target: "resolved",
            },
            onError: {
              target: "rejected",
            },
          },
        },
        resolved: {
          // Add a transition to fetch again
          on: {
            FETCH: "pending",
          },
        },
        rejected: {
          // After 2s, retry again
          after: {
            2000: {
              target: "pending",
            },
          },
        },
      },
    });
    
    const service = interpret(machine);
    
    service.onTransition((state) => {
      elBox.dataset.state = state.toStrings().join(" ");
    
      console.log(state);
    });
    
    service.start();
    
    elBox.addEventListener("click", (event) => {
      service.send("FETCH");
    });
    
    const cancelBtn = document.querySelector("#cancel");
    cancelBtn.addEventListener("click", (event) => {
      service.send("CANCEL");
    });
    
    const receiveBtn = document.querySelector("#receive");
    receiveBtn.addEventListener("click", (event) => {
      service.send("SNED_IT_ALREADY");
    });
  • 相关阅读:
    买书求如何获得折扣使价格最低
    团队开发NABC特点
    《梦断代码》读后感3
    结对开发5
    找水王问题续
    对搜狗输入法的评价
    团队项目之典型用户
    找水王问题
    电梯调度练习
    团队项目用户需求调研报告
  • 原文地址:https://www.cnblogs.com/Answer1215/p/13496914.html
Copyright © 2011-2022 走看看