我正在尝试使一个函数延迟X毫秒执行异步函数。
出于演示目的,以下是异步函数,该函数带有一个URL:
/*
* This is a simulation of an async function. Be imaginative!
*/
let asyncMock = function(url) {
return new Promise(fulfil => {
setTimeout(() => {
fulfil({
url,
data: "banana"
});
}, 10000);
});
};
我的目标是要有一个函数,该函数将接受X的url
参数,asyncMock
然后每隔X ms调用一次,直到不再有其他参数为止。
基本上,我希望每次调用都asyncMock
用X ms分隔。
例如,假设我asyncMock
连续打电话20次。通常,这20个呼叫将立即进行。我想要的是确保20个呼叫之间都存在Xms的延迟。
解决这个问题的想法是建立一个工厂,该工厂将返回一个承诺,该承诺将在X ms之后执行该功能。
let throttleFactory = function(args) {
let {
throttleMs
} = args;
let promise = Promise.resolve();
let throttleAsync = function(url) {
return promise.then(() => {
setTimeout(anUrl => {
return new Promise( fulfil => {
fulfil(asyncMock(anUrl));
});
}, throttleMs, url);
});
};
return Object.freeze({
throttleAsync
});
};
理想情况下,我将在下面的示例中使用该工厂:
let throttleFuns = throttleFactory({
throttleMs: 2000
});
console.log('running');
throttleFuns.throttleAsync('http://www.bananas.pt')
.then(console.log)
.catch(console.error);
throttleFuns.throttleAsync('http://www.fruits.es')
.then(console.log)
.catch(console.error);
throttleFuns.throttleAsync('http://www.veggies.com')
.then(console.log)
.catch(console.error);
// a ton of other calls in random places in code
这里的问题是我的throttleAsync
功能undefined
立即输出3次。我相信这可能是因为我没有promise
正确定义。
如何修复此代码以使其正常工作?
因为throttleAsync
返回调用的结果promise.then
,并且then
回调不返回任何内容。这使得通过then
解决创造的承诺具有价值undefined
。
您可能打算让它返回您正在创建的新的Promise,但是直到setTimeout
回调之前您都不会这样做。您想事先做(但还有更多,请继续阅读):
let throttleAsync = function(url) {
return promise.then(() => {
return new Promise( fulfil => {
setTimeout(anUrl => {
fulfil(asyncMock(anUrl));
}, throttleMs, url);
});
});
};
也没有理由setTimeout
像这样传递URL ,因此:
let throttleAsync = function(url) {
return promise.then(() => {
return new Promise( fulfil => {
setTimeout(() => {
fulfil(asyncMock(url));
}, throttleMs);
});
});
};
最初,我虽然promise
没有必要,但是您已经澄清了,您想确保重复的呼叫由隔开throttleMs
。为此,我们将使用上面的方法,但要进行更新promise
:
let throttleAsync = function(url) {
return promise = promise.then(() => {
// ^^^^^^^^^
return new Promise( fulfil => {
setTimeout(() => {
fulfil(asyncMock(url));
}, throttleMs);
});
});
};
这样,下一个呼叫asyncThrottle
将一直等到前一个触发后再开始下一个。
现场示例:
const throttleMs = 1000;
const asyncMock = url => url;
let promise = Promise.resolve();
let throttleAsync = function(url) {
return promise = promise.then(() => {
// ^^^^^^^^^
return new Promise( fulfil => {
setTimeout(() => {
fulfil(asyncMock(url));
}, throttleMs);
});
});
};
console.log('running');
throttleAsync('http://www.bananas.pt')
.then(console.log)
.catch(console.error);
throttleAsync('http://www.fruits.es')
.then(console.log)
.catch(console.error);
throttleAsync('http://www.veggies.com')
.then(console.log)
.catch(console.error);
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句