当前位置: 首页 > 面试题库 >

为什么我的诺言返回未定义?

洪梓
2023-03-14
问题内容

我试图制作一个延迟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);


 类似资料:
  • 问题内容: 我最近一直在搞弄api,发现有些奇怪的地方。 返回一个对象。输出 但是,如果将其写为: 这是您可以访问标题属性的标准。 所以我的问题是:为什么要在对象文字中返回一个promise,但是如果刚返回则返回一个值? 问题答案: 为什么要兑现承诺? 因为您在所有标头到达后立即收到。调用使您对尚未加载的http响应的正文有了另一个保证。另请参见[为什么来自JavaScriptfetch API的

  • 我找不到这个职位的申请书http://127.0.0.1:3001/users?name=Slava. 服务器响应“需要名称”。方法getUsers正常工作。数据库工作正常,服务器。js也能工作。我在这里寻找类似的答案,但没有合适的答案。有一些非常古老的答案,但它们并不相关。 这是一项请求:http://127.0.0.1:3001/users?name=bob (我用邮递员送信)

  • 我在chrome控制台中写了这样的表达式: 它返回:

  • 问题内容: 我有一个javascript类,每个方法都返回一个Promise。我想知道为什么在和中未定义。有没有更正确的方法来编写此代码? 我可以使用以下方法解决此问题: 但是不能完全确定为什么有必要。正在消灭? 问题答案: 始终是调用方法的对象。但是,将方法传递给时,您不会调用它!该方法将存储在某个地方,稍后再从那里调用。如果要保存,则必须这样做: 或者,如果您必须在ES6 之前的版本中进行操作

  • 问题内容: 我知道您不能使异步函数同步运行,但是如何向我的promise链添加某种顺序? 一个结果依赖于先前的promise值,当不发生时,我得到一个未定义的错误。这是一个http请求,因此它依赖于外部因素,例如我的连接执行请求的速度等。 我正在按以下方式调用上述方法。但是console.log返回未定义。 终端打印 问题答案: 尝试从第一个然后回调的返回promise

  • 问题内容: 我有一个javascript类,每个方法都返回一个Promise。我想知道为什么在和中未定义。有没有更正确的方法来编写此代码? 我可以使用以下方法解决此问题: 但是不能完全确定为什么有必要。正在消灭? 问题答案: 始终是调用方法的对象。但是,将方法传递给时,您不会调用它!该方法将存储在某个位置,稍后再从那里调用。如果要保存,则必须这样做: 或者,如果您必须在ES6之前的版本中执行此操作