承诺不返回请求值

时间:2017-10-29 15:37:17

标签: javascript promise request tampermonkey gm-xmlhttprequest

我有这个承诺:

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秒。

然后我在main函数中执行此操作:

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'永远不会执行,我的代码就会挂起。我该如何解决?我不太了解承诺,但我不明白为什么它会挂起......

2 个答案:

答案 0 :(得分:1)

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

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中没有任何内容拒绝承诺。

答案 1 :(得分:1)

  

当答案不是我想要的时候,我把它称为内部,

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

您应该promisify最低级别的异步函数GM_xmlhttpRequestsetTimeout,然后只链接您的承诺。通过{{1}来自return回调的递归调用的结果,生成的promise将以相同的结果解析:

then