Return 结果基于承诺值

Return result based on a promise value

我已经开始使用 axios,一个基于 promise 的 HTTP 客户端,但我还没有弄清楚如何 return 基于 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 函数 return 一个基于 countClients 输出的布尔值。

您不能 return 基于异步计算的同步值。 Javascript 没有故意为此提供任何方法。你可以做的是 return a Promise<boolean>:

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

更新

因此您需要将此函数提供给第三方库,并且它只适用于(x:T) => boolean类型的函数,而不适用于(x:T) => Promise<boolean>。不幸的是,您仍然无法 "wait for" 一个承诺,这不是 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);
});