Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在ReactJS中卸载组件时取消承诺_Reactjs_Promise_Cancellation - Fatal编程技术网

在ReactJS中卸载组件时取消承诺

在ReactJS中卸载组件时取消承诺,reactjs,promise,cancellation,Reactjs,Promise,Cancellation,我有一个名为“Item”的组件,它在安装时创建并调用承诺 class Item extends React.Component{ constructor(props){ super(props) this.onClick = this.onClick.bind(this) this.prom = new Promise((resolve, reject) => { setTimeout(() => re

我有一个名为“Item”的组件,它在安装时创建并调用承诺

class Item extends React.Component{
    constructor(props){
        super(props)
        this.onClick = this.onClick.bind(this)

        this.prom = new Promise((resolve, reject) => {
            setTimeout(() => resolve("PROMISE COMPLETED "+this.props.id),6000)
        })
    }

    componentDidMount(){
        this.prom.then((success) => {
            console.log(success)
        })
    }

    componentWillUnmount(){
       console.log("unmounted")
    }

    onClick(e){
        e.preventDefault()
        this.props.remove(this.props.id)
    }

    render(){
        return (
            <h1>Item {this.props.id} - <a href="#" onClick={this.onClick}>Remove</a></h1>
        )
    }
}

卸载组件时,我必须取消承诺。

您不能取消本机ES6承诺。阅读更多


但是,您可以使用非本机的promise库,如或,它们为您提供可以取消的承诺。

您可以做很多事情。最简单的方法是拒绝承诺:

this.prom = new Promise((resolve, reject) => {
     this.rejectProm = reject;
     ...
});
然后

componentWillUnmount(){
   if (this.rejectProm) {
      this.rejectProm();
      this.rejectProm = nil;
   }

   console.log("unmounted")
}
这种变化似乎对我有用。 我使用装载的实例变量创建了一个HOC,并将所有异步组件包装在其中

下面是我的代码大致如下

export function makeMountAware(Component) {
    return class MountAwareComponent extends React.Component {
        mounted = false;
        componentDidMount() {
            this.mounted = true;
        }
        componentWillUnmount() {
            this.mounted = false;
        }
        return (
            <Component 
                mounted = {this.mounted}
                {...this.props}
                {...this.state}
            />
        );
    }
}

class AsyncComponent extends React.Component {
    componentDidMount() {
        fetchAsyncData()
            .then(data => {
                this.props.mounted && this.setState(prevState => ({
                    ...prevState,
                    data
                }));
            });
    }
}
export default makeMountAware(AsyncComponent);
导出函数makeMountAware(组件){
返回类MountAwareComponent扩展React.Component{
安装=错误;
componentDidMount(){
这是真的;
}
组件将卸载(){
这是错误的;
}
返回(
);
}
}
类AsyncComponent扩展了React.Component{
componentDidMount(){
fetchAsyncData()
。然后(数据=>{
this.props.mounted和this.setState(prevState=>({
…国家,
数据
}));
});
}
}
导出默认makeMountAware(异步组件);

由于本例中使用的是超时,因此在卸载时应将其清除

class Item extends React.Component{
    constructor(props){
        super(props)
        this.onClick = this.onClick.bind(this)

        // attribute for the timeout
        this.timeout = null;

        this.prom = new Promise((resolve, reject) => {
          // assign timeout
          this.timeout = setTimeout(() => resolve("PROMISE COMPLETED "+this.props.id),6000)
        })
    }

    componentDidMount(){
        this.prom.then((success) => {
            console.log(success)
        })
    }

    componentWillUnmount(){
       // clear timeout
       clearTimeout(this.timeout);
       console.log("unmounted")
    }

我猜这将导致拒绝,您将看不到控制台日志。

我想我们无法检查此答案:,也请检查此答案:您是否试图在
this.prom
处仅调用
Promise
构造函数一次?我不确定是否完全理解此问题,但是否有帮助?第8行和第28行是查看js承诺的部分,但承诺与使用的库无关,@chitharanjan das,你的意思是说本机js承诺不能取消吗?这不会导致内存泄漏吗?因为即使在卸载组件时,承诺仍然保留对它的引用?
export function makeMountAware(Component) {
    return class MountAwareComponent extends React.Component {
        mounted = false;
        componentDidMount() {
            this.mounted = true;
        }
        componentWillUnmount() {
            this.mounted = false;
        }
        return (
            <Component 
                mounted = {this.mounted}
                {...this.props}
                {...this.state}
            />
        );
    }
}

class AsyncComponent extends React.Component {
    componentDidMount() {
        fetchAsyncData()
            .then(data => {
                this.props.mounted && this.setState(prevState => ({
                    ...prevState,
                    data
                }));
            });
    }
}
export default makeMountAware(AsyncComponent);
class Item extends React.Component{
    constructor(props){
        super(props)
        this.onClick = this.onClick.bind(this)

        // attribute for the timeout
        this.timeout = null;

        this.prom = new Promise((resolve, reject) => {
          // assign timeout
          this.timeout = setTimeout(() => resolve("PROMISE COMPLETED "+this.props.id),6000)
        })
    }

    componentDidMount(){
        this.prom.then((success) => {
            console.log(success)
        })
    }

    componentWillUnmount(){
       // clear timeout
       clearTimeout(this.timeout);
       console.log("unmounted")
    }