JavaScript Basics 0

Way to detect a desired response when recursively fetching

Practicing DatScy
CodeX
5 min readJul 25, 2024

--

Recursively fetching or running a command until a desired response occurs is useful for many types of applications. The idea seems simple because one just needs a for or while loop and a method to evaluate whether the desired response occurred. However, it can be tricky such that errors are made if the failed response is not known, and if variable to evaluate changes type.

It is common thinking to assign unknown variables as an empty object or array, like var obj = {}. Often the unknown variable, especially when performing data fetching, is an object or has similar attributes to an object (ie: length).

However, if the fetched object is not an object, it may be better to use whether a value was assigned or not (ie: null, undefined) as a trigger to detect a desired response instead of a variable attribute.

Below are four ways to detect a desired response after data or endpoint fetching.

Subfunctions and variables

var urls2try = ['https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf', 
'https://s3-us-west-2.amazonaws.com/openai-assets/research-covers/language-unsupervised/language_understanding_paper.pdf',
'https://storage.googleapis.com/on-the-way2selfrespect/yellow.png'];


async function fetch_CORS(url) {

var headers_final = {
"Content-Type": "application/json",
"Referer": url,
"Origin": "https://codesolutions2.github.io",
"Connection": "keep-alive",
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:120.0) Gecko/20100101 Firefox/120.0",
"Access-Control-Allow-Origin": "*"
};

var options = {
method : 'GET',
mode: 'cors',
headers: new Headers(headers_final),
cache: "no-cache",
crossorigin: '*',
redirect: "follow"
};

return await fetch(url, options)
.then(response => response.blob())
.then(async function(blob_object) { return blob_object; })
.catch(error => console.error("error: ", error));

}


function createSignal(initialValue) {
let value = initialValue;
const listeners = [];

function setValue(newValue) {
value = newValue;
listeners.forEach(listener => listener(value));
}

function getValue() {
return value;
}

function subscribe(listener) {
listeners.push(listener);
return () => {
const index = listeners.indexOf(listener);
if (index !== -1) {
listeners.splice(index, 1);
}
};
}

return { setValue, getValue, subscribe, };
}

Way 0: make the loop depend on a flag

Using a flag is the most straight forward method because the flag states how the loop stops. However, it is necessary to set the flag based on the desired variable response. Here, undefined or null is the desired variable response to not stop the loop. But, it may not be the case for other fetched data, it is a good idea to output both desirable and non-desirable outputs and set the trigger accordingly.

This method controls when the loop should stop depending on where you set the condition to be true, in certain cases it could be advantageous to stop the loop not immediately as a variable condition is true.

async function way0() {

// Way 0: make the loop depend on a flag in try catch
console.log('Way 0: make the loop depend on a flag in try catch');

var i = 0;
var flag = "run";
while (flag == "run" && i < urls2try.length) {
try {
console.log('url to try to fetch: ', urls2try.at(i));
var blob_object = await fetch_CORS(urls2try.at(i));
// if there is an error, it still runs everything in the try
} catch (error) {
console.log('error: ', error);
}

if (blob_object != undefined) {
flag = "stop";
}

if (flag != "stop") {
i += 1;
}
console.log('blob_object: ', blob_object);
console.log('flag: ', flag);
console.log('i: ', i);
}

}

Way 1: make the loop depend on the value of a variable

In the next three ways the trigger condition is set directly as a loop condition, so the loop stops when the condition is true. Thus faster execution can be obtained for these methods.

async function way1() {

// Way 1: make the loop depend on the value of a variable
console.log('Way 1: make the loop depend on the value of a variable');

var blob_object = undefined;
// blob_object = undefined means that blob_object = null
// blob_object = {} is not blob_object = null

var i = 0;
while (blob_object == undefined && i < urls2try.length) {
try {
console.log('url to try to fetch: ', urls2try.at(i));
blob_object = await fetch_CORS(urls2try.at(i));
// if there is a fetch error blob_object = undefined

i += 1;
} catch (error) {
console.log('error: ', error);
}

console.log('blob_object: ', blob_object);
console.log('i: ', i);
}

}

Way 2: make the loop depend on the existence of variables

I found that removing the variable from memory makes the loop stop quickest, without additional unwanted processes.

async function way2() {

// Way 2: make the loop depend on the existence of variables
console.log('Way 2: make the loop depend on the existence of variables');

var blob_object = null;
// blob_object = undefined means that blob_object = null
// blob_object = {} is not blob_object = null

var i = 0;

while (blob_object == null && i < urls2try.length) {
try {
console.log('url to try to fetch: ', urls2try.at(i));
blob_object = await fetch_CORS(urls2try.at(i));
// if there is a fetch error blob_object = undefined

i += 1;
} catch (error) {
console.log('error: ', error);
}

console.log('blob_object: ', blob_object);

if (blob_object != null) {
var out = blob_object;
delete blob_object;
}

console.log('i: ', i);
}

}

Way 3: make the loop depend on the value of functions mimicking Signals

async function way3() {

// Way 3: make the loop depend on the value of functions mimiking Signals
console.log('Way 3: make the loop depend on the value of functions mimiking Signals');

const signal = createSignal(undefined);

var i = 0;
while (signal.getValue() == undefined && i < urls2try.length) {
try {
console.log('url to try to fetch: ', urls2try.at(i));
signal.setValue(await fetch_CORS(urls2try.at(i)));
// if there is a fetch error signal = undefined

i += 1;
} catch (error) {
console.log('error: ', error);
}

console.log('signal.getValue(): ', signal.getValue());
console.log('i: ', i);
}

}

I hope these quick JavaScript tips help someone out there. Happy Practicing! 👋

💻 GitHub | 🔔 Subscribe to Practicing Datscy @ Medium | 🌷 Practicing Datscy @ Dev.to

--

--

Practicing DatScy
CodeX

Practicing coding and Data Science. Blog brand: Use logic in a clam space, like a forest, and use reliable, clear, and informative Data Science workflows!