javascript – 如何创建一个返回现有promise而不是new promise的函数?

JavaScript / Promise专家,

我希望你能帮助我,因为我不明白如何创建一个返回现有承诺而不是新承诺的函数.我做了很多研究,但每次调用函数时,所有示例都会返回一个新的承诺.

假设我有一个函数需要一些时间来处理并在每次调用时生成不同的结果.当我使用新的promise方法时,我仍然需要等待每次完成,如果我回想起这个函数,我就不会得到相同的值.

我已经包含了我创建的概念证据,可以按照需要工作(除非我忽略了一些东西).我认为这个“解决方案”很难看,因为我需要将变量移到更高的范围,每次调用函数时我仍然需要创建一个新的promise.

我此时的假设;为了使这个好的代码,函数需要返回一个现有的promise而不是一个新的,但如果其他解决方案提供相同的功能和更好的代码,请告诉我.原生ES6是首选.

谢谢!

'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);


(以下代码基于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);
你想要承诺memoise,而不是它所解决的价值.记忆works fine with promises作为结果值.

var p = null;
function notSoRandomAsyncNumber() {
  if (!p)
    p = new Promise(function(resolve) {
      setTimeout(function() {
        resolve(Math.random());
      }, 1000);
    });
  return p;
}

或者,抽象成辅助函数:

function memoize(fn) {
  var cache = null;
  return function memoized(args) {
    if (fn) {
      cache = fn.apply(this, arguments);
      fn = null;
    }
    return cache;
  };
}
function randomAsyncNumber() {
  return new Promise(res => {
    setTimeout(() => resolve(Math.random()), 1000);
  });
}
function randomAsyncNumberPlusOne() {
  return randomAsyncNumber().then(n => n+1);
}
var notSoRandomAsyncNumber = memoize(randomAsyncNumber);
var notSoRandomAsyncNumberPlusOne = memoize(randomAsyncNumberPlusOne);

(注意notSoRandomAsyncNumberPlusOne仍会在第一次调用时创建randomAsyncNumber(),而不是notSoRandomAsyncNumber())

https://stackoverflow.com/questions/31820133/how-to-create-a-function-that-returns-an-existing-promise-instead-of-new-promise

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:javascript – 如何创建一个返回现有promise而不是new promise的函数?