So I see that Promise.defer
is now deprecated and we are now supposed to use new Promise
instead. I don't see how to do this however for this example?
var Promise = require('bluebird');
var interval;
var rollDice = function (resolver) {
console.log("rolling");
if (Math.floor(Math.random() * 10) == 7) {
clearInterval(interval);
resolver.resolve();
}
}
var rollTill7 = function (ms) {
var resolver = Promise.defer();
interval = setInterval(function(){rollDice(resolver);},ms);
return resolver.promise;
}
rollTill7(100).then(function(){
console.log("rolled a 7");
});
You can wrap the Promise in a class. class Deferred { constructor(handler) { this. promise = new Promise((resolve, reject) => { this. reject = reject; this.
The . promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended. By default, type is "fx" , which means the returned Promise is resolved when all animations of the selected elements have completed.
The Promise.resolve() method "resolves" a given value to a Promise . If the value is a promise, that promise is returned; if the value is a thenable, Promise.resolve() will call the then() method with two callbacks it prepared; otherwise the returned promise will be fulfilled with the value.
The deferred. promise() method allows an asynchronous function to prevent other code from interfering with the progress or status of its internal request.
In general, it is recommended to move away from the old defer model because you want the creator of a promise to be responsible for resolving or rejecting it - this just makes the control flow a ton easier to follow. You don't want to pass on the responsibility for resolving or rejecting to some other code.
If outside code is involved in the decision to resolve or reject (such as your rollDice()
function), then it can return info which is used to resolve or reject. For example, in your code example, it can be done like this.
Note that the rollDice()
function is now just a dice rolling function that tells you whether you rolled a specific number of not. It is then used by the other function to determine control flow rather than putting control flow in the dice rolling function itself.
var rollDice = function() {
console.log("rolling");
return Math.floor(Math.random() * 10) + 1;
}
var rollTillNum = function(num, ms) {
return new Promise(function(resolve) {
var interval = setInterval(function(){
if (rollDice() === num) {
resolve();
clearInterval(interval);
}
}, ms);
});
}
rollTillNum(7, 100).then(function(){
console.log("rolled a 7");
});
Summary of Changes:
interval
variable is now contained to a local scope.rollDice()
function is now generic so it can be used in other contexts.rollDice()
now returns a 1-based value, not a 0-based value (since that's how dice work).rollTill7()
, it's now rollTillNum()
and you pass it the number you want it to achieve.While the above solution is more general (using an external function to provide feedback on whether you should resolve or not), in this specific case, if you don't even need the rollDice()
function to be externally usable, then it can just be subsumed entirely inside of the rollTillNum()
function:
var rollTillNum = function(num, ms) {
return new Promise(function(resolve) {
var interval = setInterval(function(){
if ((Math.floor(Math.random() * 10) + 1) === num) {
resolve();
clearInterval(interval);
}
}, ms);
});
}
rollTillNum(7, 100).then(function(){
console.log("rolled a 7");
});
Here's the above code made into a working demo:
document.getElementById("roll").addEventListener("click", function() {
var start = Date.now();
rollTillNum(7, 100).then(function(cnt) {
var elapsed = ((Date.now() - start) / 1000).toFixed(1);
log("It took " + elapsed + " seconds and " + cnt + " rolls to roll a 7");
});
});
var rollDice = function() {
console.log("rolling");
return Math.floor(Math.random() * 10) + 1;
}
var rollTillNum = function(num, ms) {
return new Promise(function(resolve) {
var cntr = 0;
var interval = setInterval(function(){
++cntr;
if (rollDice() === num) {
resolve(cntr);
clearInterval(interval);
}
}, ms);
});
}
function log(x) {
var div = document.createElement("div");
div.innerHTML = x;
document.body.appendChild(div);
}
<button id="roll">
Roll a 7
</button><br><br>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With