在解决初始承诺后如何在迭代数组时链接多个承诺?
How do I chain multiple promises while iterating an array after the initial promise is resolved?
我有一个函数(buildMetaData
) 执行以下操作
1. It receives an array(`items`) as a param
2. It invokes an DAO to fetch some data from a downstream service.
3. The downstream service responds with a promise (initial promise).
4. In the "then"(resolving initial promise), I need to modify the array passed in the param and return the modified array.
在第 4 步中,我映射 items
数组,在修改数组元素时,我需要调用另一个函数,该函数 returns 一个 promises 数组。我需要解决这个承诺才能设置数组元素。
我如何将这一系列承诺链接到最初的承诺?
buildMetaData(items) {
return checkoutDAO.get(items[0].id)
.then((order) => {
return items.map((item) => {
let res = {};
// some processing
const promises = this.buildItemMeta({itemType: item.type, itemId: item.id})
promises.spread((product, media) => {
res.size = this.getItemSize(product, media);
});
return res;
});
});
}
buildItemMeta({itemType, itemId}) {
const promises = [
productDAO.get(itemType), // this is a promise
];
promises.push(mediaDAO.get(itemId`)); // this is a promise
return Promise.all(promises);
}
我希望新数组能够解析 res.size
属性,但实际上 promise.all 正在创建一个新的 promise 实例,而不是链接到初始 promise。
p.s。此项目使用 continuation local storage
(cls),cls 与 async/await 存在一些已知问题,因此我无法使用 async/await 解决此问题。
如果这需要进一步解释,请告诉我。感谢您为回答这个问题所做的努力。
这会执行这些步骤,但顺序是异步的。当无法使用 async/await
时,程序性思考可能不是解决异步问题的最佳思考方式。如果您有任何问题,请告诉我。
所以这个:
- 它接收一个数组(
items
)作为参数
- 它调用 DAO 从下游服务中获取一些数据。
- 下游服务响应承诺(初始承诺)。
- 在"then"(解决初始承诺)中,我需要修改参数中传递的数组和return修改后的数组。
现在变成这样:
- 它接收一个数组(
items
)作为参数
- 它检索每个项目的元数据并保存创建的 Promises 数组
- 它存储对下游服务的调用的承诺。
- 所有承诺都已解决
- 'then' 传递了项目元数据和顺序,用作合并它们的最后阶段
请注意,我还简化了您的一些代码。
buildMetaData(items) {
const itemMetaPromises = items.map(item => this.buildItemMeta(item.type, item.id));
const orderPromise = checkoutDAO.get(items[0].id);
Promise.all([...itemMetaPromises, orderPromise])
.then(data => {
// data[0] = itemMeta([itemType,itemId]), data[1] = order
//combine order and items here
});
}
buildItemMeta(itemType, itemId) {
return Promise.all([productDAO.get(itemType),mediaDAO.get(itemId)]);
}
这是一个显示输出的模拟实现。
function buildMetaData(items) {
const itemMetaPromises = items.map(item => buildItemMeta(item.type, item.id));
const orderPromise = checkoutDAO.get(items[0].id);
Promise.all([...itemMetaPromises, orderPromise])
.then(data => {
console.log(data);
});
}
function buildItemMeta(itemType, itemId) {
return Promise.all([productDAO.get(itemType), mediaDAO.get(itemId)]);
}
checkoutDAO = {
get: () => new Promise((resolve) => {
resolve('order')
})
}
productDAO = {
get: () => new Promise((resolve) => {
resolve('product')
})
}
mediaDAO = {
get: () => new Promise((resolve) => {
resolve('media')
})
}
items = [{
type: 'itemType',
id: 'itemId'
}, {
type: 'itemType',
id: 'itemId'
}, {
type: 'itemType',
id: 'itemId'
}, {
type: 'itemType',
id: 'itemId'
}];
buildMetaData(items);
我有一个函数(buildMetaData
) 执行以下操作
1. It receives an array(`items`) as a param
2. It invokes an DAO to fetch some data from a downstream service.
3. The downstream service responds with a promise (initial promise).
4. In the "then"(resolving initial promise), I need to modify the array passed in the param and return the modified array.
在第 4 步中,我映射 items
数组,在修改数组元素时,我需要调用另一个函数,该函数 returns 一个 promises 数组。我需要解决这个承诺才能设置数组元素。
我如何将这一系列承诺链接到最初的承诺?
buildMetaData(items) {
return checkoutDAO.get(items[0].id)
.then((order) => {
return items.map((item) => {
let res = {};
// some processing
const promises = this.buildItemMeta({itemType: item.type, itemId: item.id})
promises.spread((product, media) => {
res.size = this.getItemSize(product, media);
});
return res;
});
});
}
buildItemMeta({itemType, itemId}) {
const promises = [
productDAO.get(itemType), // this is a promise
];
promises.push(mediaDAO.get(itemId`)); // this is a promise
return Promise.all(promises);
}
我希望新数组能够解析 res.size
属性,但实际上 promise.all 正在创建一个新的 promise 实例,而不是链接到初始 promise。
p.s。此项目使用 continuation local storage
(cls),cls 与 async/await 存在一些已知问题,因此我无法使用 async/await 解决此问题。
如果这需要进一步解释,请告诉我。感谢您为回答这个问题所做的努力。
这会执行这些步骤,但顺序是异步的。当无法使用 async/await
时,程序性思考可能不是解决异步问题的最佳思考方式。如果您有任何问题,请告诉我。
所以这个:
- 它接收一个数组(
items
)作为参数 - 它调用 DAO 从下游服务中获取一些数据。
- 下游服务响应承诺(初始承诺)。
- 在"then"(解决初始承诺)中,我需要修改参数中传递的数组和return修改后的数组。
现在变成这样:
- 它接收一个数组(
items
)作为参数 - 它检索每个项目的元数据并保存创建的 Promises 数组
- 它存储对下游服务的调用的承诺。
- 所有承诺都已解决
- 'then' 传递了项目元数据和顺序,用作合并它们的最后阶段
请注意,我还简化了您的一些代码。
buildMetaData(items) {
const itemMetaPromises = items.map(item => this.buildItemMeta(item.type, item.id));
const orderPromise = checkoutDAO.get(items[0].id);
Promise.all([...itemMetaPromises, orderPromise])
.then(data => {
// data[0] = itemMeta([itemType,itemId]), data[1] = order
//combine order and items here
});
}
buildItemMeta(itemType, itemId) {
return Promise.all([productDAO.get(itemType),mediaDAO.get(itemId)]);
}
这是一个显示输出的模拟实现。
function buildMetaData(items) {
const itemMetaPromises = items.map(item => buildItemMeta(item.type, item.id));
const orderPromise = checkoutDAO.get(items[0].id);
Promise.all([...itemMetaPromises, orderPromise])
.then(data => {
console.log(data);
});
}
function buildItemMeta(itemType, itemId) {
return Promise.all([productDAO.get(itemType), mediaDAO.get(itemId)]);
}
checkoutDAO = {
get: () => new Promise((resolve) => {
resolve('order')
})
}
productDAO = {
get: () => new Promise((resolve) => {
resolve('product')
})
}
mediaDAO = {
get: () => new Promise((resolve) => {
resolve('media')
})
}
items = [{
type: 'itemType',
id: 'itemId'
}, {
type: 'itemType',
id: 'itemId'
}, {
type: 'itemType',
id: 'itemId'
}, {
type: 'itemType',
id: 'itemId'
}];
buildMetaData(items);