0

I am trying to figure out a way to write below code using functional programming.

let member_found = [];

// going through 50 or more pagination until 5 are found.
while(member_found.length < 5)
{
  let member = findMember(/* calls selenium commands to visit next page */);
  if(member != undefined)
      member_found.push(member);
}

console.log(member_found) // expecting 5 values but actual is 0.

currently, the code goes into infinite loop due to non-blocking nature of js.

5
  • Is findMember an async function or doesit take a callback? Commented Jul 15, 2018 at 19:53
  • @JonasW. let member = findMember( he's maybe just missing an await, otherwise that's not an async method.. Commented Jul 15, 2018 at 19:58
  • it does take callback. That function contains lot of selenium calls to visit multiples pages. For sake of simplicity, I wrote a pseudo code. Commented Jul 15, 2018 at 20:00
  • I will answer this question, and before that, one of the bad things of your sample code. to visit next page or a lot of selenium calls or calls selenium commands is absolutely nothing to do with logic and very unclear context. Perhaps webpage stuff? If you comment to the code. Better not to use words of unclear context. Commented Jul 18, 2018 at 12:30
  • Specify the return value of findMember It's aweful manner not to speficy the key function. pseudo code does not mean to cut the core information. You add unnessary keywrords - pagenation, lots of calls, selnium command, but the most important information is hidden. Rewrite the code. Commented Jul 18, 2018 at 12:53

2 Answers 2

1

you can wrap findMember to return a promise and than you can use ES6 async\await capabilities :)

lets say you have findMember(cb) so it will be

function promiseFindMember() {
    return new Promise((res, rej) => findMember(member => res(member)))
}

in this way you will be able to write your function as following

function async foo() {
    let members = []
    while(member_found > 5) {
        let member = await promiseFindMember()
        if(member !== undefined) {
            members.push(member)
        }
    }
}

I also added an example to catch the concept and to compare between the ideas :)

function dummyCb(cb){
  console.log("Dummy run!")
  setTimeout(cb, 1000)
}

function promiseDummyCb(){
  return new Promise((res, rej) => dummyCb(() => res()))
}


async function async_hello() {
  cb_count = 0
  while(cb_count < 5) {
    await promiseDummyCb()
    cb_count += 1
  }
}

async function hello() {
  cb_count = 0
  while(cb_count < 5) {
    dummyCb()
    cb_count += 1
  }
}



hello()

Sign up to request clarification or add additional context in comments.

Comments

0

At first ensure that findMember always returns something by retrying:

const find = cb => findMember(res => res ? cb(res) : find(cb));

Now to get an array of a certain length from a callback function we could do the same thing:

const fromAsync = (fn, length, cb, arr = []) => arr.length >= length 
   ? cb(arr)
   :  fn(res => fromAsync(fn, length, cb, arr.concat(res)));

So you can finally do:

fromAsync(find, 10, result => {
  console.log(result);
});

PS: there is definitely an easier way of doing this, but you wanted a functional approach...

1 Comment

thanks! that was fast. if there is a non-functional way approach. please do share. I will check this tomorrow, its 2 am now :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.