使用函数式编程和异步的javascript while循环

使用函数式编程和异步的javascript while循环,javascript,arrays,asynchronous,while-loop,functional-programming,Javascript,Arrays,Asynchronous,While Loop,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)

我正试图找到一种使用函数式编程编写以下代码的方法

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.
let member_found=[];
//通过50个或更多分页,直到找到5个。
while(成员长度<5)
{
让member=findMember(/*调用selenium命令访问下一页*/);
如果(成员!=未定义)
找到成员。推送(成员);
}
console.log(找到成员)//应为5个值,但实际值为0。

目前,由于js的非阻塞特性,代码进入无限循环。

首先确保
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:确实有一种更简单的方法可以做到这一点,但您需要一种功能性的方法…

首先确保
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:确实有一种更简单的方法可以做到这一点,但您需要一种功能性的方法…

您可以包装findMember以返回承诺,而不是使用ES6 async\Wait功能:)

假设您有
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)
        }
    }
}
我还添加了一个示例来捕捉概念并比较各种想法:)

函数dummyCb(cb){
log(“虚拟运行!”)
设置超时(cb,1000)
}
功能承诺MYCB(){
返回新承诺((res,rej)=>dummyCb(()=>res())
}
异步函数async_hello(){
cb_计数=0
而(cb_计数<5){
等待承诺
cb_计数+=1
}
}
异步函数hello(){
cb_计数=0
而(cb_计数<5){
dummyCb()
cb_计数+=1
}
}

hello()
您可以包装findMember以返回承诺,然后可以使用ES6 async\Wait功能:)

假设您有
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)
        }
    }
}
我还添加了一个示例来捕捉概念并比较各种想法:)

函数dummyCb(cb){
log(“虚拟运行!”)
设置超时(cb,1000)
}
功能承诺MYCB(){
返回新承诺((res,rej)=>dummyCb(()=>res())
}
异步函数async_hello(){
cb_计数=0
而(cb_计数<5){
等待承诺
cb_计数+=1
}
}
异步函数hello(){
cb_计数=0
而(cb_计数<5){
dummyCb()
cb_计数+=1
}
}

hello()
findMember
异步函数还是接受回调?@JonasW<代码>让成员=findMember(他可能只是错过了等待,否则这不是一个异步方法。它需要回调。该函数包含许多selenium调用来访问多个页面。为了简单起见,我编写了一个伪代码。我将回答这个问题,在此之前,您的示例代码中有一个不好的地方。
要访问下一页
de>大量selenium调用或
调用selenium命令
与逻辑和非常不清楚的上下文完全无关。可能是网页内容?如果您对代码进行注释。最好不要使用上下文不清楚的词。指定
findMember的返回值
不指定键函数是一种令人敬畏的方式。
pseudo code
并不意味着削减核心信息。您添加了不必要的关键字-分页、大量调用、selnium命令,但最重要的信息是隐藏的。重写代码。
findMember
是异步函数还是接受回调?@JonasW。
let member=findMember(
他可能只是错过了等待,否则这不是一个异步方法。它需要回调。该函数包含许多selenium调用来访问多个页面。为了简单起见,我编写了一个伪代码。我将回答这个问题,在此之前,您的示例代码中有一个不好的地方。
要访问下一页
de>大量selenium调用或
调用selenium命令
与逻辑和非常不清楚的上下文完全无关。可能是网页内容?如果您对代码进行注释。最好不要使用上下文不清楚的词。指定
findMember的返回值
不指定键函数是一种令人敬畏的方式。
pseudo代码
并不意味着削减核心信息。你添加了不必要的关键字-分页、大量调用、selnium命令,但最重要的信息是隐藏的。重写代码。谢谢!这很快。如果有非功能性方法。请分享。我明天会检查,现在是凌晨2点:(谢谢!太快了。如果有非功能性方法,请分享。我明天会检查,现在是凌晨2点:(