gpt4 book ai didi

javascript - 使用外部文件重构 React 的 componentDidMount() 中的嵌套异步回调

转载 作者:行者123 更新时间:2023-12-03 00:24:50 25 4
gpt4 key购买 nike

我使用的是 React 的 componentDidMount(),它包含大量代码并执行两个回调。最终,在最里面的回调(即第二个回调)中,我执行 this.setState({})

最少代码

class App extends React.Component {
constructor(props) {
super(props);
this.state = { data: {} };
}

requests() {
fooCallback.request({ data: { query: userQuery } }).subscribe(({ jsonResp1 }) => {

// 100 lines of data processing with jsonResp1


// second Callback
barCallback.request({ data: { string: userString } }).subscribe(({ jsonResp2 }) => {

// 200 lines of data processing with jsonResp2
this.setState({ data: processedData })

});
});


componentDidMount() {
this.requests();
}
}

render() {
// ...
return (
// ...
);
}

}

由于 request() 方法非常庞大,它使我的主容器组件 App 变得臃肿。我已经尝试创建一个外部 js 文件(默认导出函数...)并将其导入到我的 App.js 中。然而,这不可能,可能是由于该方法的异步性质。

是否可以以某种方式减少我的 App.js?

编辑

我在许多变体中尝试过创建一个 external.js 文件:

external.js

export default async () => {
return fooCallback.request({ data: { query: userQuery } }).subscribe(({ jsonResp1 }) => {

// 100 lines of data processing with jsonResp1


// second Callback
barCallback.request({ data: { string: userString } }).subscribe(({ jsonResp2 }) => {

// 200 lines of data processing with jsonResp2
return processedData

});

return barCallback;

});

...然后导入它

App.js

import getData from './js/getData.js'
// ...
async componentDidMount() {
const response = await this.getData()
this.setState({data: response})
}

然而,没有成功。也许是创建类组件的唯一方法?

最佳答案

如果我正确理解你的问题,你想将请求函数移动到一个单独的文件,但在函数中你使用“this.setState”,它超出了组件的范围。

您将此逻辑移出组件是正确的。回调有时使用起来有点困惑,特别是当回调依赖于其他回调时,等等。

如果回调是同步的不是很好吗?您可以通过将回调包装在 Promises 中并等待解析回调结果来模拟这一点。这样,您的程序将等待第一个回调完全执行并返回数据,然后再执行需要第一个回调的输出的以下回调(您将嵌套)。

实用程序文件将类似于:

function processRespOne(fooCallback, userQuery) {
return new Promise((resolve, reject) => {
fooCallback.request({ data: { query: userQuery } }).subscribe(({ jsonResp1 }) => {
// ...process jsonResp1
// by resolving this data, it acts like a standard function "return" if the invoking expression awaits it
resolve(processedData);
});
});
}

function processRespTwo(respOneData, barCallback, userString) {
return new Promise((resolve, reject) => {
barCallback.request({ data: { string: userString } }).subscribe(({ jsonResp2 }) => {
// process jsonResp2 with the output of respOneData
resolve(processedData);
});
});
}


// here I define the function "async" so i can use the "await" syntax, so my asynchronous function acts synchronous
// Async functions return promises. So caller's can await this function.
export async function requests(fooCallback, userQuery, barCallback, userString) {
const respOneData = await processRespOne(fooCallback, userQuery);
const results = await processRespTwo(respOneData, barCallback, userString)

// anyone who is "await"ing this function will get back results
return results;
}

在 App.js 中

import { requests } from './js/getData.js';
//...
async componentDidMount() {
const results = await requests(fooCallback, userQuery, barCallback, userString);
this.setState({ results });
}

这是一个非常好的答案的链接,讨论将回调转换为 promise 以实现更同步的执行。一定要看看接受的答案中的“nodebacks”示例:How do I convert an existing callback API to promises?

关于javascript - 使用外部文件重构 React 的 componentDidMount() 中的嵌套异步回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54135038/

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