Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polling until getting specific result?

I am currently trying to add polling to my application using this link https://davidwalsh.name/javascript-polling (and many others).

I have access to the following already implemented api:

client.get('url')
// returns Promise with result of getting result from url
// for the application I am working on,
//     the URL returns json that looks like the following 
//     {status: DONE or IN PROGRESS, other values...}
// when status is DONE other values are what I will use in the application

client.post('url', {data: passAnyDataHere}) 
// sends a post request with result of sending data to url
// starts the specific job

One of the problems that I have run into is that while trying to adapt the JavaScript Polling code I linked to above, when I find out that the status is DONE, I have no way of returning the result to outside of the Promise. Can someone give me tips on how to do this? (polling until I find a specific value, and then return the value for use later)

Let me give you an example

export default function someFunction() {
    let a = client.get('/status');
    a.then( dataResult => 
      {
         if (dataResult.status == "DONE") {
            //** want to get other values in dataResult here 
            // and store it somewhere else for use later
         }
      });
    // ***want to work with results here.
    // need some way to get the status of what happened inside the .then(..) part
   //  eventually have to return success or failure and results to the frontend
   // (this part is already done)
 }

The base of the code is https://github.com/erikras/react-redux-universal-hot-example#server-side-data-fetching (uses React.js/Node.js/Redux/etc.)

Any tips/suggestions/help are/is appreciated. Thanks!

Also, the application I am working on does not use JQuery.

like image 740
cs_user2017 Avatar asked Sep 13 '17 22:09

cs_user2017


2 Answers

Here's an more extensible solution based on the post polling with async/await

Just add the following utility methods:

const poll = async function (fn, fnCondition, ms) {
  let result = await fn();
  while (fnCondition(result)) {
    await wait(ms);
    result = await fn();
  }
  return result;
};

const wait = function (ms = 1000) {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
};

Then you can call it like this:

let fetchReport = () => axios.get(reportUrl);
let validate = result => !result.data.summary;
let response = await poll(fetchReport, validate, 3000);
like image 149
KyleMit Avatar answered Oct 30 '22 01:10

KyleMit


Recent versions of Node.js, have support for async / await.

Below is an example of using it..

One major advantage of async / await, it's very easy to follow the code, and understand it's logic. If for example you wanted to extend this, to have a max try's feature, it would be trivial to do. (hint) It's just a for loop :)

let count = 0;

var client = {
  get: function () {
    return new Promise(function (resolve, reject) {
      count ++;
      setTimeout(function () {
        if (count > 4) resolve({status:'DONE',otherStuff:'Other Stuff'});
        else resolve({status: `count: ${count}`});
      }, 1000);
    });
  }
}


async function someFunction() {
  while (true) {
    let dataResult = await client.get('/status');
    console.log(dataResult.status);
    if (dataResult.status == "DONE") {
      return dataResult;
    }
  }
}

(async () => { let r = await someFunction(); console.log(r); })();
like image 20
Keith Avatar answered Oct 30 '22 01:10

Keith