为什么我的承诺不定? [英] Why is my promise returning undefined?
问题描述
背景
我试图做一个功能,将异步功能的执行延迟X ms。
出于本演示的目的,以下是异步功能,它接收一个URL:
/ *
*这是异步功能的模拟。有想象力!
* /
let asyncMock = function(url){
return new Promise(fulfill => {
setTimeout(()=> {
满足({
url,
数据:香蕉
});
},10000);
});
};
目标
我的目标是有一个函数,它将采用 url
参数 asyncMock
,然后每X ms调用一次,直到没有
基本上,我希望每个调用 asyncMock
被X ms分隔。 >
作为一个例子,我想象我连续20次呼叫$ code> asyncMock 。通常这20个电话会立即进行。我想要的是,确保20个电话中的每一个之间有Xms的延迟。
暂定
我的想法是解决这个问题,是有一个工厂,这将返回一个 promise 将在X ms后执行该功能。
让throttleFactory = function(args){
let {
$节省
} = args;
let promise = Promise.resolve();
let throttleAsync = function(url){
return promise.then(()=> {
setTimeout(anUrl =>
返回新的承诺(履行=> {
履行(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);
//代码中的随机位置中的一吨其他电话
问题
这里的问题是我的 throttleAsync
fucntion立即输出 undefined
三次。我相信这可能是因为我没有正确地定义 promise
。
问题
如何解决这个代码按照预期工作?
因为 throttleAsync
返回调用 promise.then
的结果,而然后
回调不返回任何东西这使得然后
创建的承诺的值为 undefined
。
您可能希望让您恢复您正在创建的新承诺,但是直到 setTimeout
回调才会执行此操作。你想先做(但还有更多,继续阅读):
让throttleAsync = function(url){
返回promise.then(()=> {
返回新的Promise(履行=> {
setTimeout(anUrl => {
履行(asyncMock(anUrl) );
},throttleMs,url);
});
});
};
还没有理由通过 setTimeout
像这样,所以:
让throttleAsync = function(url){
return promise。那么(()=> {
返回新的Promise(履行=> {
setTimeout(()=> {
履行(asyncMock(url));
} ,throttleMs);
});
});
};
最初我虽然承诺
没有必要,但是您已经澄清,您希望确保重复的呼叫由 throttleMs
间隔开。为了做到这一点,我们将使用上述内容,但是更新 promise
:
let throttleAsync = function(url){
return promise = promise.then(()=> {
// ^^^^^^^^
返回新的承诺(履行=> {
setTimeout(()=> {
履行(asyncMock(url));
},throttleMs);
});
});
};
这样,下一次调用 asyncThrottle
直播示例:
const throttleMs = 1000; const asyncMock = url => url; let promise = Promise.resolve(); let throttleAsync = function(url){return promise = promise.then(()=> {// ^^^^^^^^^返回新的Promise(fulfill => ; {setTimeout(()=> {fulfill(asyncMock(url));},throttleMs);});});}; console.log('running'); throttleAsync('http://www.bananas .pt()。((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);
/ p>
Background
I am trying to make a function that delays the execution of asynchronous functions by X ms.
For the purposes of this demonstration, the following is the async function, which takes an 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);
});
};
Objective
My objective here is to have a function, that will take the url
argument of asyncMock
and then call it every X ms or until there are no more arguments left.
Basically, I want every invocation of asyncMock
to be separated by X ms.
As an example, imagine I call asyncMock
20 times in a row. Normally, those 20 calls would be done immediately. What I want, it to make sure that there is Xms of delay between each of the 20 calls.
Tentative
My idea to solve this, is to have a factory, that will return a promise that will execute the function after 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
});
};
Ideally I would use this factory like in the example bellow:
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
Problem
The problem here is that my throttleAsync
fucntion outputs undefined
three times immediately. I believe this might be because I am not defining promise
properly.
Question
How can I fix this code to work as intended?
Because throttleAsync
returns the result of calling promise.then
, and the then
callback doesn't return anything. This makes the promise created by then
resolve with the value undefined
.
You probably meant to have it return the new promise you're creating, but you're not doing that until the setTimeout
callback. You want to do it prior (but there's more, keep reading):
let throttleAsync = function(url) {
return promise.then(() => {
return new Promise( fulfil => {
setTimeout(anUrl => {
fulfil(asyncMock(anUrl));
}, throttleMs, url);
});
});
};
There's also no reason to pass the URL through setTimeout
like that, so:
let throttleAsync = function(url) {
return promise.then(() => {
return new Promise( fulfil => {
setTimeout(() => {
fulfil(asyncMock(url));
}, throttleMs);
});
});
};
Originally I though the promise
there was unnecessary, but you've clarified that you want to ensure that repeated calls are "spaced out" by throttleMs
. To do that, we'd use the above, but update promise
:
let throttleAsync = function(url) {
return promise = promise.then(() => {
// ^^^^^^^^^
return new Promise( fulfil => {
setTimeout(() => {
fulfil(asyncMock(url));
}, throttleMs);
});
});
};
This way, the next call to asyncThrottle
will wait until the previous one has fired before starting the next.
Live Example:
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);
这篇关于为什么我的承诺不定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!