Assurance that request does not result in any value being returned

I have come across this interesting challenge:

function getAPI(token)
{
return new Promise((resolve, reject) => {
    console.log("Requesting 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 + " - Recursive call in 5 Seconds");
                setTimeout(function(){
                    getAPI(token);
                },5000);
            }
            else{
                console.log('Call API - Result obtained');
                resolve(response.responseText.split("_")[1]);
            }
        }
    });
});

}

I find it intriguing how I call the function within itself when the answer is not as expected, always waiting at least 5 seconds.

This leads me to the main function where I execute:

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

However, I have noticed a strange behavior. When getAPI calls itself due to unexpected answers, the '.then' block in the main function does not seem to run, causing my code to hang indefinitely. How can I address this issue? I am still learning about promises and struggling to understand why this happens...

Answer №1

When the answer is not as expected, I refer to it within itself,

However, if you fail to invoke the resolve function of the promise returned by the initial getAPI call, the promise will remain unresolved and your then callback will not receive any output.

To address this issue, consider promisifying your asynchronous functions such as GM_xmlhttpRequest and setTimeout at a fundamental level before chaining promises. By returning the result of the recursive call within a then callback, the resulting promise will resolve with the same outcome:

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];
        }
    });
}

Answer №2

Each time you invoke the getAPI function, a brand new promise is created and returned.

Instead of having getAPI call itself or creating multiple promises, consider refactoring it to only retry the specific part that needs to be retried. Here's an example:

function getAPI(token) {
    return new Promise((resolve, reject) => {
        // Function to handle the API request
        function doRequest() {
            console.log("Making API Request");
            GM_xmlhttpRequest({
                method: "GET",
                url: "URL" + token,
                onload: function(response) {
                    console.log(response.responseText);
                    if (response.responseText == "NOT_ANSWER" || response.responseText.indexOf("ERRO") > -1) {
                        // Retry if not the expected result
                        console.log(response.responseText + " - Retrying in 5 Seconds");
                        setTimeout(doRequest, 5000);
                    }
                    else {
                        console.log('Successful API Call - Returning Result');
                        resolve(response.responseText.split("_")[1]);
                    }
                }
            });
        }
        doRequest();
    });
}

Note: Your usage of getAPI includes checking for promise rejection, but the promise never gets rejected within the getAPI function.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The function persists in outputting a true result, despite the fact that it is expected to output

Currently, I am working on a NextJS project where I have a client-side form. I've been attempting to implement validation for the form by creating a separate function called validateForm(). However, no matter what input is provided, the function alway ...

Effortless pagination across various pages, utilizing diverse CSS selectors

I've integrated simple pagination into my website, but I've encountered a issue. My navigation consists of CSS tabs, each holding a unique pagination component. Here is the jQuery pagination code snippet: $(function(){ var perPage = 8; var open ...

Showing JSON object in an Angular 2 template展示JSON对象在模

When I execute the following code: stanservice.categoryDetail(this.params.get('id')) .then((data) => { this.category = JSON.stringify(data.res.rows[0]); console.log(JSON.stringify(data.res.rows[0])); }) .catch((error) => { ...

Using a JavaScript variable inside a jQuery string

Does anyone have suggestions for what I may be doing incorrectly here? VIEW DEMO HTML Code <div id="usercurrentccbox"> <div class="cardChoice"> <label for="mastercard"></label> </div> </div> JQUERY Sc ...

When extracting a value from an HTML textarea that contains multiple lines of text inputted by the user, the JSON becomes invalid

Here is the JSON format I am working with: { questionID: int studentAnswer: "String" } The issue I am facing is that the studentAnswer field is currently only capable of holding input from a single line in an HTML textarea. If I input text that spa ...

The state of my React components keeps disappearing

Within my code, I have implemented a click event on the InterestBox to trigger updates in its appearance and alter the state of its parent container. However, despite inspecting the element using React Developer Tools and attempting API requests, the stat ...

Vue 3 Router view fails to capture child's event

After some testing, I discovered that the router-view component in Vue 3 does not capture events sent from its child components. An example of this scenario is as follows: <router-view @event-test="$emit('new-test-event')" /& ...

When attempting to open a popup form by clicking a button, the code fails to function on IE6

Everything seems to be running smoothly on Firefox, however I am encountering issues with Internet Explorer 6. Here is a snippet of the problematic code: document.getElementById('layout').style.opacity = .7 document.getElementById('layout&a ...

What is the most effective way to obtain the maximum innerHeight in a browser that is not set to 100% size

Imagine the scenario where window.innerHeight = 978px with the browser not in full screen mode. However, as the browser is resized, the value of window.innerHeight will decrease accordingly. So, how can one achieve the same height = 978px when the browse ...

Invoke the Bootstrap function from a webpage

I am attempting to call an AngularJS function, but I keep receiving an error that says "Cannot read property 'forget' of undefined." Can someone please help me resolve this issue? Below is the JavaScript code I am using: var rootApp = angular.m ...

Is there a way to extract subtitles from a javascript-controlled webpage using Python?

I am attempting to scrape information from this website: Link to Website Specifically, I am trying to extract the title ''Friday Night Lights'', but I am encountering difficulties accessing it due to JavaScript on the site. To achieve ...

Executing a <SCRIPT> within an Ajax-loaded webpage

Utilizing Framework7 for my web application has been great since it allows me to load pages using Ajax, giving it an app-like feel. However, I am facing a challenge with making the "ad" code display properly on Ajax-loaded pages. If you inspect the ad co ...

Angular Compilation Blocked Due to Circular Dependency Error

Currently, I am utilizing WebStorm as my IDE to work on a personal project that I envision turning into a game in the future. The primary goal of this project is to create an Alpha version that I can showcase to potential employers, as I am actively seekin ...

`On mouseup event, changing specific text`

I've been working on a real-time HTML highlighter that surrounds selected text with span elements containing a background property. Check out the fiddle here: https://jsfiddle.net/4hd2vrex/ The issue arises when users make multiple selections, leadi ...

Verify the type of email domain (personal or corporate)

Here's an example: isPersonalEmail("<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c0aea1ada580a7ada1a9aceea3afad">[email protected]</a>") // true isPersonalEmail("<a href="/cdn-cgi/l/email- ...

The setState function in ReactJS seems to be failing to properly update the fields

I am having trouble resetting the value of my input type to empty after storing data from a controlled form element. The first method below is not working for me, even though I'm using setState to clear the input fields. Can someone help me understand ...

Pinia throws a useStore is not callable error

I have been trying to resolve the issue with (0 , pinia__WEBPACK_IMPORTED_MODULE_1__.useStore) is not a function but unfortunately, I haven't been able to find a solution. Can anyone point out what mistake I am making? Here is my store.js code: im ...

Automatically update local library dependencies with npm

Utilizing the local package dependency functionality of npm, I have implemented it in the following manner: npm install --save "file:/path/to/module" After updating my library module by running npm run build to generate dist files, I then execut ...

"When attempting to pass a string into the res.send() method in Node.js, undefined

As a new Node.js user, I'm attempting to send data back to the browser by utilizing a function called load_blocks() from an external file that I created, and then calling it with res.send(). I currently have two basic files in my setup: The first on ...

Exploring the Wonders of React Memo

I recently started delving into the world of React. One interesting observation I've made is that when interacting with componentized buttons, clicking on one button triggers a re-render of all button components, as well as the parent component. impo ...