Javascript, в то время как цикл с использованием функционального программирования и асинхронного

1

Я пытаюсь найти способ написать ниже код, используя функциональное программирование.

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.

в настоящее время код переходит в бесконечный цикл из-за неблокирующего характера js.

  • 0
    findMember - это асинхронная функция или она выполняет обратный вызов?
  • 0
    @JonasW. let member = findMember( он просто пропустил let member = findMember( , иначе это не асинхронный метод)
Показать ещё 3 комментария
Теги:
arrays
functional-programming
while-loop
asynchronous

2 ответа

2

вы можете обернуть findMember, чтобы вернуть обещание, и вы можете использовать возможности ES6 async\await :)

скажем, у вас findMember(cb) так что это будет

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

таким образом, вы сможете написать свою функцию следующим образом:

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

Я также добавил пример, чтобы поймать концепцию и сравнить между идеями :)

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()
0

Сначала убедитесь, что findMember всегда возвращает что-то, повторив:

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

Теперь, чтобы получить массив определенной длины из функции обратного вызова, мы могли бы сделать то же самое:

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

Итак, вы можете, наконец, сделать:

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

PS: определенно более простой способ сделать это, но вам нужен функциональный подход...

  • 0
    Спасибо! это было быстро. если есть нефункциональный подход. пожалуйста, поделитесь. Я проверю это завтра, сейчас 2 часа ночи :(

Ещё вопросы

Сообщество Overcoder
Наверх
Меню