gpt4 book ai didi

javascript - 如何使用异步 reducer 构建一个 promise 数组?

转载 作者:行者123 更新时间:2023-11-29 18:44:55 24 4
gpt4 key购买 nike

这是一个构建数据库查询的函数:

const buildDbQueries = async elements => elements.reduce(
async (acc, element) => {
// wait for the previous reducer iteration
const { firstDbQueries, secondDbQueries } = await acc
const asyncStuff = await someApi(element)

// leave if the API does not return anything
if (!asyncStuff) return { firstDbQueries, secondDbQueries }

// async db query, returns a Promise
const firstDbQuery = insertSomethingToDb({
id: asyncStuff.id,
name: asyncStuff.name
})

// another async db query, returns a Promise
// have to run after the first one
const secondDbQuery = insertAnotherthingToDb({
id: element.id,
name: element.name,
somethingId: asyncStuff.id
})

return {
firstDbQueries: [...firstDbQueries, firstDbQuery],
secondDbQueries: [...secondDbQueries, secondDbQuery]
}
},
// initial value of the accumulator is a resolved promise
Promise.resolve({
firstDbQueries: [],
secondDbQueries: []
})
)

此函数返回在解决之前不应执行的 promise 。

现在我们使用那个函数

const myFunc = async elements => {

const { firstDbQueries, secondDbQueries } = await buildDbQueries(elements)

// we don't want any query to run before this point

await Promise.all(firstDbQueries)
console.log('Done with the first queries')

await Promise.all(secondDbQueries)
console.log('Done with the second queries')
}

问题是:

  • 查询在我们调用 Promise.all 之前执行。
  • firstDbQueries 查询未在 secondDbQueries 之前执行,从而导致错误。

编辑

正如评论中所建议的,我尝试不使用 reduce,而是使用 for … of 循环。

const buildDbQueries = async elements => {
const firstDbQueries = []
const secondDbQueries = []

for (const element of elements) {
const asyncStuff = await someApi(element)

// leave if the API does not return anything
if (!asyncStuff) continue

// async db query, returns a Promise
const firstDbQuery = insertSomethingToDb({
id: asyncStuff.id,
name: asyncStuff.name
})

// another async db query, returns a Promise
// have to run after the first one
const secondDbQuery = insertAnotherthingToDb({
id: element.id,
name: element.name,
somethingId: asyncStuff.id
})

firstDbQueries.push(firstDbQuery)
secondDbQueries.push(secondDbQuery)

}

return { firstDbQueries, secondDbQueries }
}

这仍然会产生与使用 reduce 的先前版本完全相同的问题。

最佳答案

不要使用 async reducer。特别是不要建立一系列的 promise 。或者稍后运行的一系列东西。这在很多层面上都是错误的。

我猜你正在寻找类似的东西

function buildDbQueries(elements) {
return elements.map(element =>
async () => {
const asyncStuff = await someApi(element)
// leave if the api doesn't return anything
if (!asyncStuff) return;

await insertSomethingToDb({
id: asyncStuff.id,
name: asyncStuff.name
});
return () =>
insertAnotherthingToDb({
id: element.id,
name: element.name,
somethingId: asyncStuff.id
})
;
}
);
}

async function myFunc(elements) {
const firstQueries = buildDbQueries(elements)

// we don't want any query to run before this point

const secondQueries = await Promise.all(firstQueries.map(query => query()));
// this call actually runs the query ^^^^^^^
console.log('Done with the first queries');

await Promise.all(secondQueries.map(query => query()));
// this call actually runs the query ^^^^^^^
console.log('Done with the second queries')
}

关于javascript - 如何使用异步 reducer 构建一个 promise 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54561774/

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