承诺不返回请求的价值

Promise not returning value of request

我有这个承诺:

function getAPI(token)
{
return new Promise((resolve, reject) => {
    console.log("Request API");
    GM_xmlhttpRequest({
        method: "GET",
        url: "URL"+token,
        onload: function(response) {
            console.log(response.responseText);
            if( response.responseText == "NOT_ANSWER" || response.responseText.indexOf("ERRO") > -1 ){
                console.log(response.responseText + " - Calling Myself in 5 Seconds");
                setTimeout(function(){
                    getAPI(token);
                },5000);
            }
            else{
                console.log('Call API - Giving Result');
                resolve(response.responseText.split("_")[1]);
            }
        }
    });
});

}

当答案不是我想要的时,我会在内部调用它,但不能少于 5 秒。

然后我在主函数中这样做:

setTimeout( function(){
                getAPI(token).then((key) => {
                    console.log(key);
                    doSomethingWithKey;
                    setTimeout( function(){
                        loop();
                    },1000);
                }).catch(() => {
                    console.log('Error na api - reload page!');
                    location.reload();
                });
            },25000);

但我注意到当 getAPI 调用自身时导致答案不是我想要的,主函数中的 '.then' 永远不会执行并且我的代码挂在那里。我该如何解决?我不太了解 promises 但我不明白为什么它会挂起...

您正在创建多个承诺,因为每次调用 getAPI 都会创建并 returns 一个 new 承诺。

getAPI 不应该调用自己(或者如果调用,它应该将新的承诺传递给 resolve);相反,只需重试其中您需要重试的部分,按照以下几行:

function getAPI(token) {
    return new Promise((resolve, reject) => {
        // Function to do the request
        function doRequest() {
            console.log("Request API");
            GM_xmlhttpRequest({
                method: "GET",
                url: "URL" + token,
                onload: function(response) {
                    console.log(response.responseText);
                    if (response.responseText == "NOT_ANSWER" || response.responseText.indexOf("ERRO") > -1) {
                        // Not what we wanted, retry
                        console.log(response.responseText + " - Calling Myself in 5 Seconds");
                        setTimeout(doRequest, 5000);
                    }
                    else {
                        console.log('Call API - Giving Result');
                        resolve(response.responseText.split("_")[1]);
                    }
                }
            });
        }
        doRequest();
    });
}

旁注:您使用 getAPI 的代码正在检查承诺拒绝,但 getAPI 中没有任何内容拒绝承诺。

I call it inside of itself when the answer is not what i want,

然后你不调用你从顶部 getAPI 调用返回的承诺的 resolve,所以承诺永远不会解决,你的 then 回调永远不会得到任何结果。

您应该 promisify 您的异步函数 GM_xmlhttpRequestsetTimeout 在最低级别,然后只链接您的承诺。通过 returnthen 回调中获取递归调用的结果,生成的承诺将以相同的结果解析:

function xhrAsync(url) {
    return new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
            method: "GET",
            url: url,
            onload: resolve
        });
    });
}
function delayAsync(time) {
    return new Promise(resolve => {
        setTimeout(resolve, time);
    });
}
function getAPI(token) {
    console.log("Request API");
    return xhrAsync("URL"+token).then(response => {
//  ^^^^^^                       ^^^^
        console.log(response.responseText);
        if (response.responseText == "NOT_ANSWER" || response.responseText.includes("ERRO")) {
            console.log(response.responseText + " - Calling Myself in 5 Seconds");
            return delayAsync(5000).then(() => {
//          ^^^^^^                  ^^^^
                return getAPI(token);
//              ^^^^^^
            });
        } else {
            console.log('Call API - Giving Result');
            return response.responseText.split("_")[1];
        }
    });
}