我正在尝试从Redis获取一些数据,对其进行处理,然后将其存储回去。所以我有两个打电话给redis的电话:
_.each(guids, async (guid) => {
const targetRecordSl = await this.redisConn.ft_searchAsync(this.TargetIndex, [`@guid:{${guid}}`, 'RETURN', 1, 'sl']);
console.log('Trying to add sl:' + slId + ' to: '+guid+ ' existing value:'+ targetRecordSl[2][1]);
let sl = '';
if(targetRecordSl[2][1] != '_null' && !targetRecordSl[2][1].includes(slId)) {
sl = targetRecordSl[2][1] + ', ' + slId;
} else {
sl = slId;
}
const response = await this.redisConn.ft_addAsync(this.TargetIndex, [`${this.TargetIndex}:${guid}`, 1, 'REPLACE', 'PARTIAL', 'FIELDS', 'sl', sl]);
console.log(response);
第一个查询执行循环的所有迭代,而无需等待第二个查询完成:
Trying to add sl:11 to: P6d43d914bea8b91ece2a0a3c081b9b85 existing value:10
Trying to add sl:10 to: P6d43d914bea8b91ece2a0a3c081b9b85 existing value:10
Trying to add sl:9 to: P24e58b30a0658b8f0e5f9ce1ca0acc1f existing value:9
Trying to add sl:8 to: P7345d54686bfd491747eefd4e05d0362 existing value:8
OK
OK
OK
OK
这不是我想要的。我希望一个诺言等待另一个诺言完成:
Trying to add sl:11 to: P6d43d914bea8b91ece2a0a3c081b9b85 existing value:10
OK
Trying to add sl:10 to: P6d43d914bea8b91ece2a0a3c081b9b85 existing value:10
OK
Trying to add sl:9 to: P24e58b30a0658b8f0e5f9ce1ca0acc1f existing value:9
OK
Trying to add sl:8 to: P7345d54686bfd491747eefd4e05d0362 existing value:8
OK
请咨询。
答案 0 :(得分:2)
也许您可以尝试使用普通的for循环来做到这一点:
for (const guid of guids) {
const targetRecordSl = await this.redisConn.ft_searchAsync(this.TargetIndex, [`@guid:{${guid}}`, 'RETURN', 1, 'sl']);
console.log('Trying to add sl:' + slId + ' to: ' + guid + ' existing value:' + targetRecordSl[2][1]);
let sl = '';
if (targetRecordSl[2][1] != '_null' && !targetRecordSl[2][1].includes(slId)) {
sl = targetRecordSl[2][1] + ', ' + slId;
} else {
sl = slId;
}
const response = await this.redisConn.ft_addAsync(this.TargetIndex, [`${this.TargetIndex}:${guid}`, 1, 'REPLACE', 'PARTIAL', 'FIELDS', 'sl', sl]);
console.log(response);
}
如果这是顶级代码,则可以尝试:
async function processGuids(guids) {
for (const guid of guids) {
const targetRecordSl = await this.redisConn.ft_searchAsync(this.TargetIndex, [`@guid:{${guid}}`, 'RETURN', 1, 'sl']);
console.log('Trying to add sl:' + slId + ' to: ' + guid + ' existing value:' + targetRecordSl[2][1]);
let sl = '';
if (targetRecordSl[2][1] != '_null' && !targetRecordSl[2][1].includes(slId)) {
sl = targetRecordSl[2][1] + ', ' + slId;
} else {
sl = slId;
}
const response = await this.redisConn.ft_addAsync(this.TargetIndex, [`${this.TargetIndex}:${guid}`, 1, 'REPLACE', 'PARTIAL', 'FIELDS', 'sl', sl]);
console.log(response);
}
}
processGuids(guids)
.then(() => {
console.log('JOB DONE!!')
// Here goes your following code (if it has to be executed after processing all guids)
});
答案 1 :(得分:0)
好问题!我已经对如何异步遍历请求进行了一些研究,并在异步迭代器和生成器上找到了一些文章,这些文章提供了对每个guid
和fetch
进行迭代的可能性继续进行下一个guid
。
因此,我对您的代码做了一些修改。首先,我创建了一个函数fetchGuid
,该函数可提取单个guid
。
async function fetchGuid(guid) {
const targetRecordSl = await this.redisConn.ft_searchAsync(this.TargetIndex, [`@guid:{${guid}}`, 'RETURN', 1, 'sl']);
console.log('Trying to add sl:' + slId + ' to: '+guid+ ' existing value:'+ targetRecordSl[2][1]);
let sl = '';
if(targetRecordSl[2][1] != '_null' && !targetRecordSl[2][1].includes(slId)) {
sl = targetRecordSl[2][1] + ', ' + slId;
} else {
sl = slId;
}
const response = await this.redisConn.ft_addAsync(this.TargetIndex, [`${this.TargetIndex}:${guid}`, 1, 'REPLACE', 'PARTIAL', 'FIELDS', 'sl', sl]);
return response.
}
这是一个异步生成器函数,它将创建一个我们可以循环的迭代器。这使我们能够像您希望的那样运行顺序循环。它会一直运行到yield
出现,然后等待直到再次被调用。
async function* iterateGuids(guids) {
for (guid of guids) {
const response = await fetchGuid(guid);
yield response;
}
}
现在,第三个功能是您可以从中运行代码的地方。 getSequentialGuids
调用iterateGuids
函数并创建一个迭代器。然后,它使用for await ... of
异步遍历迭代器中的每个位置,在这种情况下,这是一个从HTTPRequest解析的承诺。
async function getSequentialGuids(guids) {
const responses = iterateGuids(guids);
for await (const response of responses) {
console.log(response);
}
}
因此,最后使用guids
函数调用您的getSequentialGuids
数组,如下所示,并看到魔术发生了。
getSequentialGuids(guids);
这对我来说也是使用异步生成器和for await ... of
语法的学习经历。因此,如果您遇到一些问题或有更多问题,请告诉我,以便我可以帮助您和我自己,从中学到东西。