I use redis in NodeJs with bluebird, however Promise.race does not behave as expected with this set of tools.
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
})
The last console.log call should execute after the first redis update finished, but it is called only after all of are done.
Your code has created a race condition with uncertain timing. Basically, you have five .then()
handlers that are all getting queued at about the same time and you can't really tell which ones will execute before the others. Promise.race().then()
will be scheduled as soon as your first promise resolves, but if other things are also scheduled around the same time, you have no control over which ones run first.
If you want to get only the first client.setAsync()
that finishes, then you should use Promise.race()
the way it was designed to be used and let it return to you the first resolved value. To do that, you need to give each promise the appropriate resolved value so Promise.race()
can then tell you which promise resolved first:
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
});