摘要:poll()
具有回调函数可用;我没有找到任何使用本机承诺。我试图适应一些没有成功。我还没有解决的问题是,当setTimeout调用的函数的第一个实例结束而没有任何返回时,监听它的.then()
会将终止视为false
和{{1} }。 reject()
终止,不会听取以后的回复。
问题:如何最好地帮助then()
功能,以便以后.then()
或resolve()
返回?
这篇文章的其余部分是详细的。阅读有用的内容。
可用的民意调查功能:我喜欢(https://stackoverflow.com/users/1249219/om-shankar)Om Shankar在Calling a function every 60 seconds中的回复。 David Walsh的民意调查()非常相似(https://davidwalsh.name/essential-javascript-functions)。两者都使用回调并且运行良好。我发现
poll in javascript
其中包括使用reject()
的{{1}} - 仅承诺。
这是我尝试用本机承诺实现的。
poll()
预期用途:
bluebird
我认为这种方式正在运行(如果我错了,请纠正我):在* 1处致电/**
* poll - checks repeatedly whether a condition exists. When the condition
* exists, returns a resolved standard promise. When it has checked
* long enough, returns a rejected standard promise.
* @param {function} fn - a caller-supplied synchronous function that
* detects a condition in the environment. Returns true if the
* condition exists; otherwise false.
* @param {number} timeout - maximum number of milliseconds
* the caller wants to check param fn();
* reject() the promise at the expiration of param timeout.
* @param {number} interval - minimum number of milliseconds between
* calls to param fn(); resolve() the promise when param fn() first
* reports true.
* @return {promise} - resolved when param fn() returns true;
* rejected if param timeout expires without param fn() returning true
*/
function poll(fn, timeout, interval) {
let endTime = Number(new Date()) + (timeout || 2000)
interval = interval || 250
return Promise.resolve *2
.then(() => { *3
(function p(fn, endTime, interval) {
if (fn()) { return Promise.resolve("Condition is satisfied.") } *4
else {
if (Number(new Date()) <= endTime) {) *5
window.setTimout(p, interval, fn, endTime, interval) *6
}
else {
return Promise.reject("Past endTime; condition not satisfied")
}
}
}()) *7
}) *8
}
后,我们会立即在* 2处返回待处理的承诺,以便function waitIsOver() { return (<desired condition exists>) }
poll(waitIsOver, 2000, 250) *1
知道等。然后,我们将该承诺的poll()
函数称为* 3。函数poll()
开始。如果then()
(在p()
以外称为fn()
)在* 4返回true,我们就会很好:我们返回p()
,而waitIsOver()
在* 1获取它所寻求的坚定承诺。
然后是不好的部分:如果resolve()
在* 4返回false而我们在* {5}内{(1}}(很可能; poll()
之后不太可能发生第一次调用),我们在* 6使用fn()
要求JS在堆栈中做一个注释,以便在endTime
时间后实例化另一个endTime
。之后,setTimeout()
的第一个实例终止于* 7。在* 8,p()
知道interval
在没有返回任何内容的情况下终止,并将条件解释为返回p()
和then()
;与p()
一起,承诺得以解决,永远不会改变。但是,false
到期后,reject()
的后续实例会启动。它返回的任何东西都会丢失;承诺得到解决,reject()
在不需要的路径上发送执行后终止。
How do I convert an existing callback API to promises?推荐使用Promise构造函数的方法,interval
调用p()
,then()
调用resolve()
。我尝试了这种技术,但是在遇到问题之前我遇到了callback()
函数结束的相同问题。我还没有弄清楚如何让reject()
作为耐心等待作为回调函数。
这就提出了问题。再次:
问题:如何最好地帮助errback
功能,以便以后从then()
或then()
返回?
答案 0 :(得分:4)
如何最好地帮助.then()函数留下来以便以后返回 来自resolve()或reject()
在解决或拒绝基础承诺时调用.then()
处理程序。永远不会在此之前调用它。因此,如果您想在调用.then()
处理程序时延迟,那么您将延迟解析或拒绝基础承诺,直到适当的时间。
正如你从我的评论中可以看出的那样,很难准确地说出你想要完成什么,因为你不仅仅描述了你想要实现的直接目标。
鉴于此,我猜你想要完成的是什么。一个明确的问题可能会在几分钟内得到这样的答案。
如果您只是想重复轮询您的函数,直到它返回真值或直到超时时间到达,您可以使用标准的ES6承诺执行此操作:
function poll(fn, timeout, interval) {
return new Promise(function(resolve, reject) {
// set timeout timer
var timeoutTimer = setTimeout(function() {
clearInterval(intervalTimer);
reject("Past endTime; condition not satisfied");
}, timeout);
// set polling timer
var intervalTimer = setInterval(function() {
if (fn()) {
clearTimeout(timeoutTimer);
clearInterval(intervalTimer);
resolve("Condition is satisfied");
}
}, interval);
});
}
poll(yourFounction, 5000, 100).then(function(result) {
// succeeded here
}).catch(function(err) {
// timed out here
})
或者,使用Bluebird promise库,您可以使用其.timeout()
方法执行此操作:
function poll(fn, timeout, interval) {
return new Promise(function(resolve, reject) {
// set polling timer
var intervalTimer = setInterval(function() {
if (fn()) {
clearInterval(intervalTimer);
resolve("Condition is satisfied");
}
}, interval);
}).timeout(timeout, "Past endTime; condition not satisfied");
}
poll(yourFounction, 5000, 100).then(function(result) {
// succeeded here
}).catch(function(err) {
// timed out here
})
请注意,这两个方案都返回一个promise,然后当poll()
函数完成时,它们会调用resolve或拒绝新的promise,然后触发任何.then()
个处理程序被调用。
P.S。我应该补充一点,这一切都假设你的fn()
是一个同步函数,它返回一个真值或假值(这是你的代码似乎假设的)。如果您的fn()
实际上是具有回调或承诺的异步函数,则需要将其考虑在设计中。在编写正确使用的代码之前,您必须向我们展示函数的调用约定。
答案 1 :(得分:2)
既然你说你发现有回调的轮询功能,这基本上归结为&#34;我如何宣传某些内容?&#34;
使用BluebirdJS的Promisify:
var poleYouFoundThatHasCallback = require('somePollLibrary');
var Promise = require('bluebird');
var poll = Promise.Promisify(poleYouFoundThatHasCallback);
poll.then((res) => {
//dostuff with res here
}).catch(err => console.log(err))
你也可以为它施加超时和傻笑。
来自docs的示例和示例:
var Promise = require("bluebird");
var fs = Promise.promisifyAll(require('fs'));
fs.readFileAsync("huge-file.txt").timeout(100).then(function(fileContents) {
}).catch(Promise.TimeoutError, function(e) {
console.log("could not read file within 100ms");
});