gpt4 book ai didi

javascript - 需要帮助相关的异步函数执行流程(await、promises、node.js)

转载 作者:行者123 更新时间:2023-11-30 15:00:02 25 4
gpt4 key购买 nike

如果你能帮助我解决以下情况,我将不胜感激:

给定函数:

async function getAllProductsData() {
try {
allProductsInfo = await getDataFromUri(cpCampaignsLink);
allProductsInfo = await getCpCampaignsIdsAndNamesData(allProductsInfo);
await Promise.all(allProductsInfo.map(async (item) => {
item.images = await getProductsOfCampaign(item.id);
}));
allProductsInfo = JSON.stringify(allProductsInfo);
console.log(allProductsInfo);
return allProductsInfo;
} catch(err) {
handleErr(err);
}
}

该函数在服务器启动时被触发,它从其他站点收集事件信息:获取数据 (getDataFromUri()),然后从数据名称和 ID 中提取 (getCpCampaignsIdsAndNamesData()),然后获取每个事件的产品图片 (getProductsOfCampaign) ());

我还有带有以下代码的 express.app:

app.get('/products', async (req, res) => {
if (allProductsInfo.length === undefined) {
console.log('Pending...');
allProductsInfo = await getAllProductsData();
}
res.status(200).send(allProductsInfo);
});

问题描述:

  1. 启动服务器,等待几秒钟直到 getAllProductsData() 被执行,执行 '/products' GET 请求,一切正常!
  2. 启动服务器并立即触发'/products' GET 请求'(为此我添加了带有 console.log('Pending...') 表达式的 IF),返回损坏的结果:它包含所有事件名称、ID,但没有图像数组。

    • [{"id":"1111","name":"一些名字"},{"id":"2222","name":"其他名字"}],在我期待的时候
    • [{"id":"1111","name":"一些名字","images":["URI","URI"...]}...]

非常感谢您在以下方面的帮助:

  • 解释异步执行的流程,以及为什么不等待将图像数组添加到对象就发送结果?
  • 如果您知道涵盖我的主题的一些有用的文章/规范部分,我将不胜感激。

谢谢。

最佳答案

使用全局变量 allProductsInfo,然后触发多个异步使用它的并发函数是一个很大的问题。这会产生各种竞争条件,您必须认为自己幸运只有没有图像数据。

您可以通过将 allProductsInfo 设为局部变量轻松解决此问题,或者至少不使用它来存储 getDataFromUrigetCpCampaignsIdsAndNamesData 的中间结果> - 为这些使用不同的(本地!)变量。

但是,即使您这样做,您也可能会多次触发 getAllProductsData,这不应导致错误,但仍然效率低下。在全局变量中存储一个 promise 要容易得多,通过一次调用信息收集过程来初始化这个一次,并且每次都等待它 - 当它已经完成时不会被注意到.

async function getAllProductsData() {
const data = await getDataFromUri(cpCampaignsLink);
const allProductsInfo = await getCpCampaignsIdsAndNamesData(allProductsInfo);
await Promise.all(allProductsInfo.map(async (item) => {
item.images = await getProductsOfCampaign(item.id);
}));
console.log(allProductsInfo);
return JSON.stringify(allProductsInfo);
}

const productDataPromise = getAllProductsData();
productDataPromise.catch(handleErr);
app.get('/products', async (req, res) => {
res.status(200).send(await productDataPromise);
});

当然,您可能还希望仅在数据加载后启动您的服务器(或向其添加 /products 路由),并在此之前简单地提供状态 500。此外,您还应该考虑在 promise 被拒绝后命中路由时会发生什么 - 不确定 handleErr 做了什么。

关于javascript - 需要帮助相关的异步函数执行流程(await、promises、node.js),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46684326/

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