title: How to create a function that returns an existing promise instead of new promise?
body: <p>JavaScript/Promise experts,</p>
  
  <p>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 <strong>a lot</strong> of research, but all examples return a new promise every time the function is called.</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>Thanks!</p>
  
  <p>-</p>
  
  <pre><code>'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></pre>
  
  <p>-
  (code below is based on the feedback from Bergi;</p>
  
  <pre><code>'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);
  </code></pre>