gpt4 book ai didi

javascript - 同步填充/修改数组并在 promise 内返回修改后的数组

转载 作者:行者123 更新时间:2023-12-03 13:34:56 24 4
gpt4 key购买 nike

我对 ReactJS 和 redux 还很陌生,所以我以前从未真正使用过这个。我正在从项目中的 API 调用检索数据。我想通过向对象添加新属性来修改数据。但是,由于代码不是同步运行的,因此将返回未修改的数组(我假设)而不是修改后的数组。

export function loadThings() {
return dispatch => {
return dispatch({
type: 'LOAD_THINGS',
payload: {
request: {
url: API_GET_THINGS_ENDPOINT,
method: 'GET'
}
}
}).then(response => {
let things = response.payload.data;
// Retrieve all items for the loaded "things"
if(things) {
things.forEach((thing, thingIndex) => {
things[thingIndex].items = []
if (thing.hasOwnProperty('channels') && thing.channels) {
thing.channels.forEach(channel => {
if (channel.hasOwnProperty('linkedItems') && channel.linkedItems) {
channel.linkedItems.forEach(itemName => {
dispatch(loadItems(itemName)).then(
item => things[thingIndex].items.push(item) // push the items inside the "things"
)
})
}
})
}
})
}
things.forEach(data => console.log(data.items.length, data.items)) // data.items.length returns 0, data.items returns a populated array
return things // return the modified array
}).catch(error => {
//todo: handle error
return false
})
}
}

如您所见,我执行了一个 API 调用,该调用返回名为 response 的数据。该数组填充有所有“事物”。如果 things 存在,我想加载名为“items”的额外信息。根据 things 数组中的信息,我将执行另一个 API 调用(通过调度 loadItems 函数来完成),该调用返回另一个 promise。根据该 API 调用结果中的数据,我将推送到 things 对象的 items 属性(这是一个数组)。

正如您在评论中看到的,如果我循环遍历 things 数组并记录我刚刚创建的 items 属性,它基本上返回 0 作为长度,这表示在修改 things 数组之前返回 things 数组。

我想知道两件事:

  • 是什么导致我的代码异步运行。是不是dispatch(loadItems(itemName)) 函数,因为它返回一个 promise ?
  • 我如何能够同步执行我的代码?

请注意:此函数 loadThings() 还会返回一个 Promise(如果您不熟悉 redux)。

您可能有兴趣了解我自己尝试如何修复代码

由于我无法理解代码异步运行的逻辑,所以我一直在尝试无望的东西。例如将代码包装在另一个 Promise.all 中,并在该 Promise 中返回修改后的数组。我使用该 Promise 的 then 方法来修改 things 数组,其结果完全相同。可能是因为 return things 正在该 promise 之外执行。

我真的很想知道发生了什么

编辑我已按照要求将 loadItems() 代码添加到问题中:

export function loadItems(itemName) {
return dispatch => {
const url = itemName ? API_GET_ITEMS_ENDPOINT + `/${itemName}` : API_GET_ITEMS_ENDPOINT;
return dispatch({
type: 'LOAD_ITEMS',
payload: {
request: {
url: url,
method: 'GET'
}
}
}).then(response => {
return response.payload.data
})
}
}

最佳答案

我的方法是映射 things,为包装在 Promise.all 中的所有项目创建 Promise 数组,这会为您提供一个 数组>Promise.all 的。

然后你在另一个 Promise.all 中返回 things 和这个 Promise 数组,在下一个 then block 中,你可以将数组分配给每个 thing 用一个简单的 for 循环:

export function loadThings() {
return dispatch => {
return dispatch({
type: 'LOAD_THINGS',
payload: {
request: {
url: API_GET_THINGS_ENDPOINT,
method: 'GET'
}
}
}).then(response => {
let things = response.payload.data;
// Retrieve all items for the loaded "things"
const items = things.map((thing) => {
const thingItems = []
if (thing.hasOwnProperty('channels') && thing.channels) {
thing.channels.forEach(channel => {
if (channel.hasOwnProperty('linkedItems') && channel.linkedItems) {
channel.linkedItems.forEach(itemName => {
thingItems.push(dispatch(loadItems(itemName)));
});
}
});
}

return Promise.all(thingItems);
});

return Promise.all([things, Promise.all(items)])
})
.then(([things, thingItems]) => {
things.forEach((thing, index) => {
thing.items = thingItems[index];
})

return things;
})
.catch(error => {
//todo: handle error
return false
})
}
}

编辑:您需要将 dispatch(loadItmes(itemName)) 调用直接推送到 thingItems

关于javascript - 同步填充/修改数组并在 promise 内返回修改后的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61608367/

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