More Questions About Asynchronous Programming

Status
Not open for further replies.

p0_boy

anti-kumbaya
Veteran
Joined
Mar 26, 2019
Messages
64
Reaction score
29
First Language
English
Primarily Uses
RMMV
Hello again, e'rybody-

I have the following JSON object, stored in a variable ($gameSystem._ipLookupJSON):

Each of the keys in the object above is a URL.

I am trying to write a function ($._findService()) that:
  1. Goes through each key one by one,
  2. Sends that key to another function ($._urlExists()), which checks if the URL is valid / responsive,
  3. If it is- create a new variable object / array with only that key and its elements (City, Country, IP); and then-
  4. "breaks" the function because it has already found a working URL, returning the new object that was created.
Here is $._findService(), as I have it so far:
Code:
$._findService = function(json_data) {
    Object.keys(json_data).some(async function(k){
        var check_for = "http://" + k;
        var url_check = await $._urlExists(check_for);
        url_check.then(function(value){
            if (value === true) {
                var service_to_use = json_data[k];
                return service_to_use;
            };
        });
    });
};
And here is $._urlExists():
Code:
    $._urlExists = function(url_to_check) {
      // check if string  is valid url format, source: https://stackoverflow.com/a/5717133
      var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
      '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
      '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
      '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
      '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
      '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
      if (!!pattern.test(url_to_check) == true) {
          return new Promise(function(resolve, reject) {
              // check if url exists, source: https://stackoverflow.com/a/24297372
              var reader = new XMLHttpRequest();
              reader.open('get', url_to_check, true);
              reader.onreadystatechange = (function() {
                  if (reader.readyState === 4) {
                      //check to see whether request for the file failed or succeeded
                      if ((reader.status == 200) || (reader.status == 0)) {
                          return resolve(true);
                      } else {
                          return resolve(false);
                      };
                  };
              });
              reader.send(null);
          });
      };
    };
Unfortunately, I am running into the same problem I had in my previous post, where (because $._urlExists() uses asynchronous programming) $._findService() just returns an undefined value rather than the new array.

As you can see, I am trying to use async/await to avoid this... but I am not sure if I am doing it correctly. There could be other mistakes that I am making, I have just been staring at these particular lines of code for so long I feel as if I am at my wit's end already.

I am hoping that somebody brighter than me can throw me a bone and let me know how I can get this working.

As always, thanks in advance and have a great weekend!


Addendum
I guess I was asking too heady of a question.

Anyway, reading and Googl'ing led me to a solution on flaviocopes.com which made me break down $._findService() into three different functions:
Code:
    const isServiceAvailable = async url_to_check => {
      console.log(url_to_check);
      return await subaybay.an._urlExists("http://" + url_to_check);
    };
 
    const checkServices = async(json_data) => {
        return await Promise.all(Object.keys(json_data).map(url_to_check => isServiceAvailable(url_to_check)));
    };
 
    $._findService = function(json_data) {
        var url_check = checkServices(json_data);
        url_check.then(function(values) {
            for (i = 0; i < values.length; i++) {
                if (values[i] === true) {
                    service_to_use = new Array();
                    service_to_use.push(Object.keys(json_data)[i]);
                    console.log(service_to_use);
                    return service_to_use;
                };
            };
        });
    };
I am still running into problems in the last part of $._findService()-
Code:
                if (values[i] === true) {
                    service_to_use = new Array();
                    service_to_use.push(Object.keys(json_data)[i]);
                    console.log(service_to_use);
                    return service_to_use;
                };
I am having problems creating a new variable object / array with the working URL and its elements (City, Country, IP); and getting it to return the new array.

However, I will toil on and probably get it soon. Stay tuned.

Addendum 2:
I am so close.
Code:
    $._findService = function(json_data) {
      var url_check = checkServices(json_data);
      url_check.then(function(values) {
        for (i = 0; i < values.length; i++) {
          if (values[i] === true) {
            var service_to_use = new Promise(function(resolve, reject) {
              var result = [];
              console.log('json_data[Object.keys(json_data)[i]]:');
              console.log(json_data[Object.keys(json_data)[i]]);
              result.push(json_data[Object.keys(json_data)[i]]);
              console.log('Object.keys(json_data)[i]:');
              console.log(Object.keys(json_data)[i]);
              result.unshift(Object.keys(json_data)[i]);
              resolve(result);
            });
            service_to_use.then(function(value) {
              console.log('value:');
              console.log(value);
              return value;
            });
          };
        };
      });
    };
I just can't get $._findService() to return the service_to_use result. Sigh.


Addendum 3
filipe at stackoverflow was able to give me the solution I was looking for:
Code:
const isServiceAvailable = async url_to_check => {
    console.log(url_to_check);
    return await subaybay.an._urlExists("http://" + url_to_check);
};

const checkServices = async(json_data) => {
    return await Promise.all(Object.keys(json_data).map(url_to_check => isServiceAvailable(url_to_check)));
};

$._findService = async(json_data) {
    const values = await checkServices(json_data);

    for (let i = 0; i < values.length; i++) {
        if (values[i] === true) {
            const result = [];
            result.push(json_data[Object.keys(json_data)[i]]);
            result.unshift(Object.keys(json_data)[i]);
            console.log(result);
            return result;
        }
    }
};
And then use:
Code:
const result = await $._findService($gameSystem._ipLookupJSON);
Phew.
 
Last edited:

Kes

Veteran
Veteran
Joined
Aug 3, 2012
Messages
22,299
Reaction score
11,712
First Language
English
Primarily Uses
RMVXA
[closed]IgnoreMe[/closed]
 
Status
Not open for further replies.

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

How many parameters is 'too many'??
Yay, now back in action Happy Christmas time, coming back!






Back in action to develop the indie game that has been long overdue... Final Fallacy. A game that keeps on giving! The development never ends as the developer thinks to be the smart cookie by coming back and beginning by saying... "Oh bother, this indie game has been long overdue..." How could one resist such? No-one c
So I was playing with filters and this looked interesting...

Versus the normal look...

Kind of gives a very different feel. :LZSexcite:
To whom ever person or persons who re-did the DS/DS+ asset packs for MV (as in, they are all 48x48, and not just x2 the pixel scale) .... THANK-YOU!!!!!!!!! XwwwwX

Forum statistics

Threads
105,849
Messages
1,016,981
Members
137,563
Latest member
cexojow
Top