gpt4 book ai didi

javascript - 为什么我的 promise 返回未定义?

转载 作者:搜寻专家 更新时间:2023-11-01 00:16:54 24 4
gpt4 key购买 nike

背景

我正在尝试制作一个将异步函数的执行延迟 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);

});
};

目标

我的目标是拥有一个函数,它将采用 asyncMockurl 参数,然后每隔 X 毫秒调用它一次,或者直到没有更多参数为止。

基本上,我希望 asyncMock 的每次调用都以 X 毫秒分隔。

举个例子,假设我连续调用了 20 次 asyncMock。通常,这 20 个电话会立即完成。我想要的是确保 20 个调用中的每个调用之间有 Xms 的延迟。

暂定

我想解决这个问题,是有一个工厂,它会返回一个 promise将在 X 毫秒后执行函数。

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 三次。我相信这可能是因为我没有正确定义 promise

问题

如何修复此代码使其按预期工作?

最佳答案

因为 throttleAsync 返回调用 promise.then 的结果,而 then 回调不返回任何内容。这使得由 then 创建的 promise 以值 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);

关于javascript - 为什么我的 promise 返回未定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42577647/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com