这是我使用await / async的漂亮代码
monthlyBuckets(req, res) {
const monthlyBuckets = []
const now = DateTime.local()
let date = config.beginningOfTime
while (date < now) {
monthlyBuckets.push({
epoch: date.toMillis(),
month: date.month,
year: date.year,
actions: await redis.get(`actions_monthly_${date.year}_${date.month}`),
interested: await redis.scard(`sinterested_monthly_${date.year}_${date.month}`),
adventurous: await redis.scard(`sadventurous_monthly_${date.year}_${date.month}`),
active: await redis.scard(`sactive_monthly_${date.year}_${date.month}`),
})
date = date.plus({month: 1})
}
res.status(200).json(monthlyBuckets)
}
我喜欢它,但是不并行执行这么多请求会导致请求时间接近3秒。
所以,这是我没有异步/等待的丑陋解决方案,只是保证:
monthlyBuckets(req, res) {
const monthlyBuckets = []
const actions = []
const interested = []
const adventurous = []
const active = []
const now = DateTime.local()
let date = config.beginningOfTime
let entryCount = 0
while (date < now) {
monthlyBuckets.push({
epoch: date.toMillis(),
month: date.month,
year: date.year,
})
actions.push(redis.get(`actions_monthly_${date.year}_${date.month}`))
interested.push(redis.scard(`sinterested_monthly_${date.year}_${date.month}`))
adventurous.push(redis.scard(`sadventurous_monthly_${date.year}_${date.month}`))
active.push(redis.scard(`sactive_monthly_${date.year}_${date.month}`))
date = date.plus({month: 1})
entryCount++
}
const data = await Promise.all(actions.concat(interested).concat(adventurous).concat(active))
for (let i = 0; i < entryCount; i++) {
monthlyBuckets[i].actions = data[i]
monthlyBuckets[i].interested = data[entryCount + i]
monthlyBuckets[i].adventurous = data[entryCount * 2 + i]
monthlyBuckets[i].active = data[entryCount * 3 + i]
}
res.status(200).json(monthlyBuckets)
}
}
不好看,但是可以在200毫秒内完成工作
我能拥有漂亮高效吗?
答案 0 :(得分:3)
上面的代码存在问题,您正在尝试:
尽管这不是一个错误,但可能导致难以“阅读”代码。
代码可以写为:
while (date < now) {
let dateData = {
epoch: date.toMillis(),
month: date.month,
year: date.year,
};
let promiseData = Promise.all([
dateData, // dataData is cast(made to) automatically into a promise
redis.get(`actions_monthly_${date.year}_${date.month}`),
redis.scard(`sinterested_monthly_${date.year}_${date.month}`),
redis.scard(`sadventurous_monthly_${date.year}_${date.month}`),
redis.scard(`sactive_monthly_${date.year}_${date.month}`)
]).then([data, actions, interested, adventurous, active] => {
// process the data here for each month
data.actions = actions;
data.interested = interested;
data.adventurous = adventurous;
data.active = active;
return data;
});
monthlyBuckets.push(promiseData);
date = date.plus({month: 1});
}
const data = await Promise.all(monthlyBuckets);
res.status(200).json(data);
改变的是
分组承诺没有错,例如:
Promise.all([
Promise.all([ ...]),
Promise.all([ ...]),
singlePromise,
...
]);
处理承诺,例如:
promiseProcessed1 = promise1.then(callback1);
promiseProcessed12 = Promise.all([promise1, promise2]).then(callback2);
或重用promise,例如:
promiseProcessed1 = promise1.then(callback1);
promiseProcessed12 = Promise.all([promise1, promise2]).then(callback2);
resultDatapromise = Promise.all([promise1, promise2, promiseProcessed1, promiseProcessed12]).then(callback2);
参考
答案 1 :(得分:0)
在这种情况下,采取不同的步骤可能会有所帮助。示例:
function createBucket(date, ops){
const b = {
epoch: date.toMillis(),
month: date.month,
year: date.year,
actions: redis.get(`actions_monthly_${date.year}_${date.month}`),
interested: redis.scard(`sinterested_monthly_${date.year}_${date.month}`),
adventurous: redis.scard(`sadventurous_monthly_${date.year}_${date.month}`),
active: redis.scard(`sactive_monthly_${date.year}_${date.month}`),
}
const promised = ['actions','interested', 'adventurous', 'active'];
promised.forEach(p => ops.push(async () => {b[p] = await b[p]}));
}
async function monthlyBuckets(req,res){
const monthlyBuckets = []
const now = DateTime.local()
let date = config.beginningOfTime
const ops = [];
while (date < now) {
monthlyBuckets.push(createBucket(date,ops));
date = date.plus({month: 1})
}
await Promise.all(ops);
res.status(200).json(monthlyBuckets)
}