【问题标题】:Return result based on a promise value根据承诺值返回结果
【发布时间】:2017-06-02 18:32:06
【问题描述】:

我已经开始使用 axios,一个基于 Promise 的 HTTP 客户端,但我还没有弄清楚如何根据 Promise 值返回结果。

这是我的代码的简化版本:

function isUnique(cif) {
    countClients(cif).then(function(count) {
        return (count == 0);
    });
}

function countClients(cif) {
    return axios.get('/api/clients?cif=' + cif)
        .then(function(response) {
            let clients = response.data;
            return clients.length;
        })
        .catch(function(error) {
            console.log(error);
            return false;
        });
}

我希望 isUnique 函数根据 countClients 输出返回一个布尔值。

【问题讨论】:

    标签: javascript promise axios


    【解决方案1】:

    您不能根据异步计算返回同步值。 Javascript 没有故意提供这种方法。你可以做的是返回一个Promise<boolean>

    function isUnique(cif) {
        return countClients(cif).then(function(count) {
            return (count == 0);
        });
    }
    

    更新

    所以你需要将此函数提供给第三方库,它只适用于(x:T) => boolean类型的函数,而不适用于(x:T) => Promise<boolean>。不幸的是,你仍然不能“等待”一个承诺,这不是 JavaScript 事件循环的工作方式。

    正确的解决方案

    使用支持异步验证功能的验证库。

    解决方法

    我不建议这样做,但您可以在操作之前缓存所有可能使用的值。

    例如,假设这是您调用第三方的方式:

    function isUnique(cif) {
        return true; // Dummy mock
    }
    var result = ThirdParty.doValidation(isUnique);
    console.log(result);
    

    相反,您可以编写如下内容:

    function isUnique(cif) {
        return countClients(cif).then(function(count) {
            return (count == 0);
        });
    }
    function getRelevantCifs() {
        return axios.get("/api/all-client-cifs");
    }
    
    var isUniqueCache = new Map();
    function isUniqueCached(cif) {
        return isUniqueCache.get(cif);
    }
    function buildCache() {
        return getRelevantCifs().then(cifs => {
            return Promise.all(cifs.map(cif => {
                return isUnique(cif).then(isUniqueResult => {
                    isUniqueCache.set(cif, isUniqueResult);
                });
            }));
        });
    }
    buildCache().then(() => {
        var result = ThirdParty.doValidation(isUniqueCached);
        console.log(result);
    });
    

    【讨论】:

    • 我没有提到验证库使用了 isUnique 函数,它必须返回 boolean 而不是 Promise<boolean>
    • @FlorinFrătică 不幸的是,您仍然不能这样做。请参阅我更新的答案以获取解决方法。顺便说一句,我们在谈论哪个验证库?
    • 我正在使用jQuery Validation 插件。它开箱即用,带有从 Envato 购买的模板,并且它被扩展,因此只能通过编写 HTML 代码来使用,所以我想我宁愿使用另一个库来进行 AJAX 调用。 Request 似乎是一个不错的选择。
    • 为什么使用 Request 会更好?您将面临同样的问题。您无法摆脱 ajax 调用的异步特性。你必须学会​​如何处理它。
    猜你喜欢
    • 2019-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-06
    • 2017-09-10
    • 2016-04-30
    • 1970-01-01
    • 2017-02-03
    相关资源
    最近更新 更多