在Node中,我正在使用bluebird的Promise.all
异步执行Promises。我不想等待所有Promises解决,然后再将结果发送回客户端。相反,我希望在解决每个Promise时立即流式传输结果。这可能吗?我的研究表明并非如此,但我认为值得将其推广到社区。 p>
以下是代码(不尝试实现流式传输):
async bulkExecution(req, res) {
try {
const { assets } = req.body;
let thePromises = _.map(assets, (asset) => {
return onePromise(asset);
});
// I want to stream each Promise result to client as it resolves
let results = await Promise.all(thePromises);
return res.status(200).send(results);
} catch (err) {
return res.status(500).send(err);
}
}
答案 0 :(得分:0)
我认为您必须遍历所有的Promise,并对每个Promise做一个.then()
,写一个部分响应,然后在所有Promise都完成后关闭响应。这样的事情应该起作用。响应的顺序可能与promise数组的顺序不同。例如,下面的示例将首先返回第二个Promise。
let res = {
write: (data) => {console.log(data)},
end: () => {}
};
let promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 500);
});
let promise2 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});
let promises = [promise1, promise2];
let count = 0;
promises.forEach((promise) => {
promise.then((data) => {
res.write(data);
count++;
if (count >= promises.length){
res.end();
}
})
})
修改为以JSON格式编写。
let res = {
write: (data) => {
console.log(data)
},
end: () => {}
};
let promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve({foo:"bar"});
}, 500);
});
let promise2 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve({bar:"foo"});
}, 300);
});
let promises = [promise1, promise2];
let count = 0;
res.write("[");
promises.forEach((promise) => {
promise.then((data) => {
res.write(JSON.stringify(data));
count++;
if (count >= promises.length) {
res.write("]");
res.end();
} else {
res.write(",");
}
})
})
像这样的流JSON并不常见,但是可以用来减少服务器使用的内存量。这是因为您无需在发送响应之前在内存中创建完整响应。客户端仍然需要足够的内存才能将整个对象读入内存。