简体   繁体   English

for循环中的模态确认Promise反应

[英]Modal confirmation in a for loop Promise react

I am trying to solve this problem but i am hitting a wall now.我正在尝试解决这个问题,但我现在碰壁了。

https://codepen.io/trinhdh/pen/ZEKJqXO https://codepen.io/trinhdh/pen/ZEKJqXO

So, i do have an array and just want to console.log each item of in the array.所以,我确实有一个数组,只想控制台.log 数组中的每个项目。 However, if an item === 1 then a confirmation modal will pop-up and ask again to print it out.但是,如果一个项目 === 1 那么一个确认模式将弹出并再次要求打印出来。 If you see the console.如果你看到控制台。 在此处输入图片说明

The problem is 'delete 2' and 'delete 3' is print out first.问题是“删除 2”和“删除 3”首先打印出来。 I would like to have it wait until i confirmed the modal box from 1.我想让它等到我从 1 确认模态框。

Expected output 'delete 1' -> 'delete 2' -> 'delete 3' .预期输出'delete 1' -> 'delete 2' -> 'delete 3' How can i make 'delete 2' and 'delete 3' wait for the first one.我怎样才能让“删除 2”和“删除 3”等待第一个。

I have tried to put it in new Promise() but its still not working.我试图将它放在new Promise()但它仍然无法正常工作。 I really need a suggestion.我真的需要一个建议。

Thank you谢谢

/* I am getting close */

const {  Modal, Button, Space  } = antd;
const {  ExclamationCircleOutlined  } = icons;
const axios = require('axios');

class LocalizedModal extends React.Component {
    state = {input: [1,2,3]}
  
    handleModalConfirm(i) {
      return await axios.get('http://webcode.me').then(res => {
        res.data = 1 /* I am just faking the res.data = 1.*/

        if (res.data === 1) {
          const a = new Promise((res, rej) => {
            Modal.confirm({
              title: "Confirm",
              content: "Are you sure you want to delete " + i,
              icon: <ExclamationCircleOutlined />,
              okText: "Yes",
              cancelText: "No",
              onOk: () => {
                console.log("delete " + i);
                res();
              },
              onCancel: () => {
                rej();
              }
            });
          });
          await a;
        } else {
          console.log("delete " + i);
        }
      })
    }
  
    handleConfirmDelete = async (input) => {
    return new Promise(async (resolve, reject) => {
      for (const i of input) {
        this.handleModalConfirm(i)
      }
      resolve();
    }).catch((e) => console.log(e));
  };

  handleDelete = () => {
    Modal.confirm({
      title: 'Confirm', 
      icon: <ExclamationCircleOutlined />,
      content: 'Are you sure you want to delete this ?',
      okText: 'Yes',
      cancelText: 'No',
      onOk: () => {
         this.handleConfirmDelete(this.state.input)
    }
    });
  }
  

   render() {
    return (
      <>
        <Button onClick={() => this.handleDelete()}>Delete All</Button>
      </>
    );
  }
}


ReactDOM.render(
  <Space>
    <LocalizedModal />
  </Space>,
  mountNode,
);

The onOk in your modal needs to be blocking, meaning that you have to have JS stop the processing of the loop.您的模态中的onOk需要阻塞,这意味着您必须让 JS 停止循环的处理。 However, there's no way to pause the processing of the loop due to the Modal being a "non-blocking" element.但是,由于Modal是“非阻塞”元素,因此无法暂停循环的处理。 Therefore, instead of using a forEach loop, write a recursive function and call the function again within the onOk prop.因此,不要使用 forEach 循环,而是编写一个递归函数并在onOk再次调用该函数。

  parseAndWait = arr => {
    const arrCopy = [...arr]
    const ele = arrCopy.shift()
    if (ele === 1) {
      Modal.confirm({
        title: "Confirm",
        icon: <ExclamationCircleOutlined />,
        content: "Are you sure you want to delete " + ele,
        okText: "Yes",
        cancelText: "No",
        onOk: () => {
          // process the remaining elements of the array only
          // after the user has clicked ok
          console.log("delete " + ele);
          if (arrCopy.length > 0) {
            this.parseAndWait(arrCopy);
          }
        }
      })
    } else {
      console.log("delete " + ele);
      if (arrCopy.length > 0) {
        this.parseAndWait(arrCopy);
      }
    }
  }
  
  handleConfirmDelete = (input) => {
    this.parseAndWait(input)
  }

Just use for (const i of input) as foreach does not work with async and use a promise and await with async method.只需使用for (const i of input)因为 foreach 不适用于 async 并使用 promise 并使用 async 方法等待。

const {  Modal, Button, Space  } = antd;
const {  ExclamationCircleOutlined  } = icons;

class LocalizedModal extends React.Component {
  state = {input: [1,2,3]}
 
  handleConfirmDelete = async (input) => {
    return new Promise(async (resolve, reject) => {
      for (const i of input) {
        if (i === 1) {
          const a = new Promise((res, rej) => {
            Modal.confirm({
              title: "Confirm",
              content: "Are you sure you want to delete " + i,
              icon: <ExclamationCircleOutlined />,
              okText: "Yes",
              cancelText: "No",
              onOk: () => {
                console.log("delete " + i);
                res();
              },
              onCancel: () => {
                rej();
              }
            });
          });
          await a;
        } else {
          console.log("delete " + i);
        }
      }
      resolve();
    }).catch((e) => console.log(e));
  };
  
  handleDelete = () => {
    Modal.confirm({
      title: 'Confirm', 
      icon: <ExclamationCircleOutlined />,
      content: 'Are you sure you want to delete this ?',
      okText: 'Yes',
      cancelText: 'No',
      onOk: () => {
         this.handleConfirmDelete(this.state.input)
    }
    });
  }
  

   render() {
    return (
      <>
        <Button onClick={() => this.handleDelete()}>Delete All</Button>
      </>
    );
  }
}


ReactDOM.render(
  <Space>
    <LocalizedModal />
  </Space>,
  mountNode,
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM