gpt4 book ai didi

javascript - React.js 告诉你取消 promise 。官方 promise 不能取消。我应该怎么做?

转载 作者:行者123 更新时间:2023-12-03 14:54:39 28 4
gpt4 key购买 nike

为了防止对未安装的 React 组件进行幻像更新,React 会告诉您 cancel any pending promises卸载时在组件上(例如获取附加数据的 promise )。使用 Bluebird Promise 很容易做到这一点,它有一个 .cancel()导致 .then() 的方法和 .catch()处理程序从不响应。

但是,ES6 Promises 不支持取消。另外,ES7 的 asyncawait仅使用原生 Promises,不支持任何插入式替换(例如 Bluebird)。这意味着如果你想在 React 中取消 Promise,就像他们告诉你的那样,你必须使用 .then().catch()并且还必须在本地 Promise 方法上放置一个中间人,例如 fetch()以便可以取消。

这真的是 React 所期望的吗?

最佳答案

仅供引用。
使用 CPromise 包,您可以取消您的 promise 链,包括嵌套的。它支持 AbortController 和生成器作为 ECMA 异步函数的替代品。目前该项目处于测试阶段。
生成器使用 Live Demo :

import CPromise from "c-promise2";

const chain = CPromise.resolve()
.then(function* () {
const value1 = yield new CPromise((resolve, reject, { onCancel }) => {
const timer = setTimeout(resolve, 1000, 3);
onCancel(() => {
console.log("timer cleared");
clearTimeout(timer);
});
});
// Run promises in parallel using CPromise.all (shortcut syntax)
const [value2, value3] = yield [
CPromise.delay(1000, 4),
CPromise.delay(1000, 5)
];
return value1 + value2 + value3;
})
.then(
(value) => {
console.log(`Done: ${value}`); // Done: 12 (without calling cancel)
},
(err) => {
console.log(`Failed: ${err}`); // Failed: CanceledError: canceled
}
);

setTimeout(() => chain.cancel(), 100);
输出:
timer cleared 
Failed: CanceledError: canceled
那里的所有阶段都是完全可取消/可中止的。
这是一个将它与 React Live Demo 一起使用的示例
export class TestComponent extends React.Component {
state = {};

async componentDidMount() {
console.log("mounted");
this.controller = new CPromise.AbortController();
try {
const json = await this.myAsyncTask(
"https://run.mocky.io/v3/7b038025-fc5f-4564-90eb-4373f0721822?mocky-delay=2s"
);
console.log("json:", json);
await this.myAsyncTaskWithDelay(1000, 123); // just another async task
this.setState({ text: JSON.stringify(json) });
} catch (err) {
if (CPromise.isCanceledError(err)) {
console.log("tasks terminated");
}
}
}

myAsyncTask(url) {
return CPromise.from(function* () {
const response = yield cpFetch(url); // cancellable request
return yield response.json();
}).listen(this.controller.signal);
}

myAsyncTaskWithDelay(ms, value) {
return new CPromise((resolve, reject, { onCancel }) => {
const timer = setTimeout(resolve, ms, value);
onCancel(() => {
console.log("timeout cleared");
clearTimeout(timer);
});
}).listen(this.controller.signal);
}

render() {
return (
<div>
AsyncComponent: <span>{this.state.text || "fetching..."}</span>
</div>
);
}
componentWillUnmount() {
console.log("unmounted");
this.controller.abort(); // kill all pending tasks
}
}
Using Hooks and cancel method
import React, { useEffect, useState } from "react";
import CPromise from "c-promise2";
import cpFetch from "cp-fetch";

export function TestComponent(props) {
const [text, setText] = useState("fetching...");

useEffect(() => {
console.log("mount");
const promise = cpFetch(props.url)
.then(function* (response) {
const json = yield response.json();
setText(`Delay for 2000ms...`);
yield CPromise.delay(2000);
setText(`Success: ${JSON.stringify(json)}`);
})
.canceled()
.catch((err) => {
setText(`Failed: ${err}`);
});

return () => {
console.log("unmount");
promise.cancel();
};
}, [props.url]);

return <p>{text}</p>;
}

关于javascript - React.js 告诉你取消 promise 。官方 promise 不能取消。我应该怎么做?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59568434/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com