Javascript Async会等待在redux thunk函数中返回数据
我一直在尝试用来自mongo db realm数据库的数据填充我的redux存储。 无论何时我运行下面的函数,它都会正常执行,但问题是数据会延迟,最终无法到达我的redux存储 我的thunk功能:Javascript Async会等待在redux thunk函数中返回数据,javascript,typescript,react-native,redux,redux-thunk,Javascript,Typescript,React Native,Redux,Redux Thunk,我一直在尝试用来自mongo db realm数据库的数据填充我的redux存储。 无论何时我运行下面的函数,它都会正常执行,但问题是数据会延迟,最终无法到达我的redux存储 我的thunk功能: export const addItemsTest = createAsyncThunk( "addItems", async (config: any) => { try { return await Realm.open(config).th
export const addItemsTest = createAsyncThunk(
"addItems",
async (config: any) => {
try {
return await Realm.open(config).then(async (projectRealm) => {
let syncItems = await projectRealm.objects("Item");
await syncItems.addListener((x, changes) => {
x.map(async (b) => {
console.log(b);
return b;
});
});
});
} catch (error) {
console.log(error);
throw error;
}
}
);
还有我的redux减速机:
extraReducers: (builder) => {
builder.addCase(addItemsTest.fulfilled, (state, { payload }: any) => {
try {
console.log("from add Items");
console.log(payload);
state.push(payload);
} catch (error) {
console.log(error)
}
});
}
预期结果:
我的redux存储应该有这些数据一次addItemsTest
返回一些内容:
[{
itemCode: 1,
itemDescription: 'Soccer Ball',
itemPrice: '35',
partition: 'partitionValue',
},
{
itemCode: 2,
itemDescription: 'Base Ball',
itemPrice: '60',
partition: 'partitionValue',
}
]
实际结果:
混合语法
您将await
/async
和Promise.then()
语法以一种非常混乱的方式组合在一起。混合使用这两种语法不是错误,但我不建议这样做。坚持使用justwait
/async
无效回报
您的操作实际上现在没有返回任何值,因为您的内部then
函数没有返回任何值。唯一的返回
在内部,然后
在x.map
回调中wait syncItems
是映射器的返回值,而不是函数的返回值
现在,你的恶棍是这样做的:
- 打开连接
- 从域中获取项目
- 向记录更改的项目添加侦听器
- 返回一个
,该承诺解析为承诺
无效
export const addItemsTest = createAsyncThunk(
"addItems",
async (config: any) => {
try {
const projectRealm = await Realm.open(config);
const syncItems = await projectRealm.objects("Item");
console.log(syncItems);
return syncItems;
} catch (error) {
console.log(error);
throw error;
}
}
);
如果没有日志记录,可以简化为:
export const addItemsTest = createAsyncThunk(
"addItems",
async (config: any) => {
const projectRealm = await Realm.open(config);
return await projectRealm.objects("Item");
}
);
您不需要捕获错误,因为createAsyncThunk
将通过调度错误操作来处理错误
编辑:侦听更改
似乎您的目的是将redux存储与领域集合中的更改同步。因此,您希望向调用dispatch
的集合添加一个侦听器,并执行一些操作来处理更改
在这里,我假设此操作使用包含集合中所有项的数组。大概是这样的:
const processItems = createAction("processItems", (items: Item[]) => ({
payload: items
}));
替换您所在州的整个阵列是最简单的方法。当您用相同的版本替换项对象时,这将导致一些不必要的重新渲染,但这不是什么大问题
或者,您可以传递的特定属性,例如插入
,并在reducer中逐个处理它们
为了添加分派processItems
的侦听器,我们需要访问两个变量:realmconfig
和reduxdispatch
。您可以在组件中或通过调用“init”操作来执行此操作。我认为没有太大区别。如果需要,您可以在reducer中对“init”操作做出响应
下面是一个添加侦听器的函数。Realm.Results
对象是“类似数组”的,但不完全是数组,因此我们使用[…x]
将其强制转换为数组
仅供参考,此函数可能会引发错误。如果在createAsyncThunk
中使用,这是很好的,但是在组件中,我们希望捕获这些错误
const loadCollection = async (config: Realm.Configuration, dispatch: Dispatch): Promise<void> => {
const projectRealm = await Realm.open(config);
const collection = await projectRealm.objects<Item>("Item");
collection.addListener((x, changes) => {
dispatch(processItems([...x]));
});
}
直接添加侦听器:
const EffectComponent = ({config}: {config: Realm.Configuration}) => {
const dispatch = useDispatch();
useEffect( () => {
// async action in a useEffect need to be defined and then called
const addListener = async () => {
try {
loadCollection(config, dispatch);
} catch (e) {
console.error(e);
}
}
addListener();
}, [config, dispatch]);
/* ... */
}
混合语法
您将await
/async
和Promise.then()
语法以一种非常混乱的方式组合在一起。混合使用这两种语法不是错误,但我不建议这样做。坚持使用justwait
/async
无效回报
您的操作实际上现在没有返回任何值,因为您的内部then
函数没有返回任何值。唯一的返回
在内部,然后
在x.map
回调中wait syncItems
是映射器的返回值,而不是函数的返回值
现在,你的恶棍是这样做的:
- 打开连接
- 从域中获取项目
- 向记录更改的项目添加侦听器
- 返回一个
承诺
,该承诺解析为无效
解决方案
我相信你想要的是:
export const addItemsTest = createAsyncThunk(
"addItems",
async (config: any) => {
try {
const projectRealm = await Realm.open(config);
const syncItems = await projectRealm.objects("Item");
console.log(syncItems);
return syncItems;
} catch (error) {
console.log(error);
throw error;
}
}
);
如果没有日志记录,可以简化为:
export const addItemsTest = createAsyncThunk(
"addItems",
async (config: any) => {
const projectRealm = await Realm.open(config);
return await projectRealm.objects("Item");
}
);
您不需要捕获错误,因为createAsyncThunk
将通过调度错误操作来处理错误
编辑:侦听更改
似乎您的目的是将redux存储与领域集合中的更改同步。因此,您希望向调用dispatch
的集合添加一个侦听器,并执行一些操作来处理更改
在这里,我假设此操作使用包含集合中所有项的数组。大概是这样的:
const processItems = createAction("processItems", (items: Item[]) => ({
payload: items
}));
替换您所在州的整个阵列是最简单的方法。当您用相同的版本替换项对象时,这将导致一些不必要的重新渲染,但这不是什么大问题
或者,您可以传递的特定属性,例如插入
,并在reducer中逐个处理它们
为了添加分派processItems
的侦听器,我们需要访问两个变量:realmconfig
和reduxdispatch
。您可以在组件中或通过调用“init”操作来执行此操作。我认为没有太大区别。如果需要,您可以在reducer中对“init”操作做出响应
下面是一个添加侦听器的函数。Realm.Results
对象是“类似数组”的,但不完全是数组,因此我们使用[…x]
将其强制转换为数组
仅供参考,此函数可能会引发错误。如果在createAsyncThunk
中使用,这是很好的,但是在组件中,我们希望捕获这些错误
const loadCollection = async (config: Realm.Configuration, dispatch: Dispatch): Promise<void> => {
const projectRealm = await Realm.open(config);
const collection = await projectRealm.objects<Item>("Item");
collection.addListener((x, changes) => {
dispatch(processItems([...x]));
});
}
直接添加侦听器:
const EffectComponent = ({config}: {config: Realm.Configuration}) => {
const dispatch = useDispatch();
useEffect( () => {
// async action in a useEffect need to be defined and then called
const addListener = async () => {
try {
loadCollection(config, dispatch);
} catch (e) {
console.error(e);
}
}
addListener();
}, [config, dispatch]);
/* ... */
}
对不起,我在代码上犯了一个错误,请你在同一期之后重新阅读一遍好吗。您仍然没有返回任何内容。似乎他正在尝试一个侦听器,该侦听器侦听数据库中的更改,然后在有人进行更改时添加任何项目