node redis bluebird - Promise.race 错误行为

node redis bluebird - Promise.race wrong behavior

我在 NodeJs 中使用 redis 和 bluebird,但是 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 更新完成后执行,但只有在所有更新完成后才会调用。

您的代码创建了时间不确定的竞争条件。基本上,您有五个 .then() 处理程序,它们大约同时排队,您无法真正判断哪些处理程序先于其他处理程序执行。 Promise.race().then() 将在您的第一个 promise 解决后立即安排,但如果其他事情也大约在同一时间安排,您无法控制先 运行 的事情。

如果你只想获得第一个完成的 client.setAsync(),那么你应该使用 Promise.race() 它设计的使用方式,让第一个 return 给你解决的价值。为此,您需要为每个承诺提供适当的解决值,以便 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
});