JavaScript/Promise experts,
I hope you can help me, because I don't understand how I can create a function that returns an existing promise instead of a new promise. I have done a lot of research, but all examples return a new promise every time the function is called.
Assume I have a function that takes some time to process and generates a different result every time it is being called. When I use the new promise method then I still need to wait to complete every time and I don't get the same value if I recall the function.
I have included proof of concept I have created that works as desired (unless I have overlooked something). I think this "solution" is ugly, because I need to move variables to a higher scope and I still need to create a new promise every time the function is called.
My assumption at this moment; to make this nice code the function needs to return an existing promise instead of a new one, but if other solutions provide the same functionality and nicer code then please let me know. Native ES6 is preferred.
Thanks!
-
'use strict';
var p;
var q;
var randomNumber = function() {
return new Promise(function(resolve) {
console.log(`p: ${p}`);
if (typeof p === 'undefined') {
setTimeout(function() {
p = Math.random();
resolve(p);
}, 1000);
} else {
resolve(p);
}
});
};
var randomNumberPlusOne = function() {
return new Promise(function(resolve) {
console.log(`q: ${q}`);
if (typeof q === 'undefined') {
randomNumber()
.then(function(p) {
q = p + 1;
resolve(q);
});
} else {
resolve(q);
}
});
};
var showResult = function(result) {
console.log();
console.log(`r: ${result}`);
};
randomNumber()
.then(showResult);
randomNumber()
.then(randomNumberPlusOne)
.then(showResult);
randomNumberPlusOne()
.then(showResult);
setTimeout(function() {
console.log();
console.log('setTimeout:');
console.log();
randomNumber()
.then(showResult);
randomNumber()
.then(randomNumberPlusOne)
.then(showResult);
randomNumberPlusOne()
.then(showResult);
}, 2000);
-
(code below is based on the feedback from Bergi;
'use strict';
var randomNumber = (function() {
var p = null;
return function() {
console.log('p:');
console.log(p);
console.log();
if (!p) {
p = new Promise(function(resolve) {
setTimeout(function() {
resolve(Math.random());
}, 1000);
});
}
return p;
};
})();
var randomNumberPlusOne = (function() {
var q = null;
return function() {
console.log('q:');
console.log(q);
console.log();
if (!q) {
q = randomNumber()
.then(function(p) {
return p + 1;
});
}
return q;
};
})();
var showResult = function(result) {
console.log(`r: ${result}`);
console.log();
};
randomNumber()
.then(showResult);
randomNumber()
.then(randomNumberPlusOne)
.then(showResult);
randomNumberPlusOne()
.then(showResult);
setTimeout(function() {
console.log();
console.log('setTimeout:');
console.log();
randomNumber()
.then(showResult);
randomNumber()
.then(randomNumberPlusOne)
.then(showResult);
randomNumberPlusOne()
.then(showResult);
}, 2000);
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…