节点redis bluebird - Promise.race错误的行为

问题描述 投票:0回答:1

我在NodeJs中使用redis的redis,但Promise.race在这套工具中的表现并不像预期的那样。

const redis = require('redis');
const bluebird = require('bluebird');
const client = redis.createClient();

bluebird.promisifyAll(redis.RedisClient.prototype);

const values = [];
const promise1 = client.setAsync("key1", 1).then(() => values.push(1));
const promise2 = client.setAsync("key2", 2).then(() => values.push(2));
const promise3 = client.setAsync("key3", 3).then(() => values.push(3));
const promise4 = client.setAsync("key4", 4).then(() => values.push(4));

Promise.race([promise1,promise2,promise3,promise4]).then(() => {
    console.log(values); // 4 values, instead of the expected 1
})

最后一次console.log调用应在第一次redis更新完成后执行,但只有在完成所有redis更新后才会调用。

node.js redis bluebird node-redis
1个回答
0
投票

您的代码创建了一个具有不确定时间的竞争条件。基本上,你有五个.then()处理程序,几乎在同一时间排队,你无法确定哪些将在其他人之前执行。 Promise.race().then()将在您的第一个承诺结算后立即安排,但如果其他事情也在同一时间安排,您无法控制哪些事先运行。

如果你想只获得完成的第一个client.setAsync(),那么你应该按照设计使用的方式使用Promise.race()并让它返回给你第一个解析的值。为此,您需要为每个承诺提供适当的解决值,以便Promise.race()可以告诉您首先解决了哪个承诺:

const promise1 = client.setAsync("key1", 1).then(() => 1);
const promise2 = client.setAsync("key2", 2).then(() => 2);
const promise3 = client.setAsync("key3", 3).then(() => 3);
const promise4 = client.setAsync("key4", 4).then(() => 4);

Promise.race([promise1,promise2,promise3,promise4]).then(val => {
    console.log(val);    // will be resolved value of first promise to resolve
});
© www.soinside.com 2019 - 2024. All rights reserved.