如何创建 returns 现有承诺而不是新承诺的功能?
How to create a function that returns an existing promise instead of new promise?
JavaScript/Promise 专家,
我希望你能帮助我,因为我不明白如何创建一个 return 现有承诺而不是新承诺的函数。我做了 很多 研究,但是所有示例 return 每次调用函数时都会有一个新的承诺。
假设我有一个函数,它需要一些时间来处理并且每次被调用时都会产生不同的结果。当我使用新的 promise 方法时,我仍然需要每次都等待完成,如果我记得这个函数,我不会得到相同的值。
我已经包含了我创建的可以按预期工作的概念证明(除非我忽略了什么)。我认为这个 "solution" 很难看,因为我需要将变量移动到更高的范围,并且每次调用函数时我仍然需要创建一个新的承诺。
此刻我的假设;为了使这个漂亮的代码函数需要 return 一个现有的承诺而不是一个新的承诺,但是如果其他解决方案提供相同的功能和更好的代码那么请告诉我。首选原生 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);
尝试建议的新变量方法。 Promises 被设计成单发的,所以它取决于实现。您尝试做的更多是在事件或 reactivex 领域。如果您使用 jquery 那么您可以使用他们的事件方案。 nodejs 站点上提供了一个更干净的。因为它不需要任何其他东西,所以它在浏览器中运行。 rxjs 是流处理的精华,但它是一个大库,需要一些学习。值得 - 因为相同的知识在多种语言中对客户端和服务器很有用。您甚至可以通过许多其他方式从承诺中设置流。
您需要 memoise the promise, not the value that it resolves with. Memoisation 作为结果值。
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()
)
JavaScript/Promise 专家,
我希望你能帮助我,因为我不明白如何创建一个 return 现有承诺而不是新承诺的函数。我做了 很多 研究,但是所有示例 return 每次调用函数时都会有一个新的承诺。
假设我有一个函数,它需要一些时间来处理并且每次被调用时都会产生不同的结果。当我使用新的 promise 方法时,我仍然需要每次都等待完成,如果我记得这个函数,我不会得到相同的值。
我已经包含了我创建的可以按预期工作的概念证明(除非我忽略了什么)。我认为这个 "solution" 很难看,因为我需要将变量移动到更高的范围,并且每次调用函数时我仍然需要创建一个新的承诺。
此刻我的假设;为了使这个漂亮的代码函数需要 return 一个现有的承诺而不是一个新的承诺,但是如果其他解决方案提供相同的功能和更好的代码那么请告诉我。首选原生 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);
尝试建议的新变量方法。 Promises 被设计成单发的,所以它取决于实现。您尝试做的更多是在事件或 reactivex 领域。如果您使用 jquery 那么您可以使用他们的事件方案。 nodejs 站点上提供了一个更干净的。因为它不需要任何其他东西,所以它在浏览器中运行。 rxjs 是流处理的精华,但它是一个大库,需要一些学习。值得 - 因为相同的知识在多种语言中对客户端和服务器很有用。您甚至可以通过许多其他方式从承诺中设置流。
您需要 memoise the promise, not the value that it resolves with. Memoisation
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()
)