Javascript 使用返回承诺的函数筛选数组

Javascript 使用返回承诺的函数筛选数组,javascript,arrays,ecmascript-6,es6-promise,Javascript,Arrays,Ecmascript 6,Es6 Promise,给定 长度为3,因为返回的是承诺,而不是值。有没有一种方法可以使用返回承诺的函数过滤数组 注意:在本例中,fs.stat已替换为setTimeout,有关具体代码,请参阅。执行此操作的有效方法(但似乎太混乱): 同样,看起来太乱了。这是一种有效的方法(但看起来太乱了): 同样,它看起来太凌乱了。正如评论中提到的,Array.prototype.filter是同步的,因此不支持承诺。 由于您现在(理论上)可以使用ES6对内置类型进行子类化,因此您应该能够添加自己的异步方法来包装现有的筛选函数: 注

给定

长度为3,因为返回的是承诺,而不是值。有没有一种方法可以使用返回承诺的函数过滤数组

注意:在本例中,fs.stat已替换为setTimeout,有关具体代码,请参阅。

执行此操作的有效方法(但似乎太混乱):

同样,看起来太乱了。

这是一种有效的方法(但看起来太乱了):


同样,它看起来太凌乱了。

正如评论中提到的,
Array.prototype.filter
是同步的,因此不支持承诺。

由于您现在(理论上)可以使用ES6对内置类型进行子类化,因此您应该能够添加自己的异步方法来包装现有的筛选函数:

注意:我已经注释掉了子类化,因为Babel还不支持数组

class AsyncArray/*扩展了Array*/{
建造师(arr){
this.data=arr;//代替数组子类化
}
filterAsync(谓词){
//复制一份数组,在我们完成时它可能会发生变异
const data=Array.from(this.data);
//使用谓词将所有元素转换为承诺数组
//作为承诺
返回Promise.all(data.map((元素,索引)=>谓词(元素,索引,数据)))
//使用承诺的结果调用基础同步筛选器函数
。然后(结果=>{
返回数据。筛选器((元素,索引)=>{
返回结果[索引];
});
});
}
}
//改为创建子类的实例
设arr=newasyncArray([1,2,3,4,5]);
//传递你自己的谓词
arr.filterAsync(异步(元素)=>{
返回新承诺(res=>{
设置超时(()=>{
res(元素>3);
}, 1);
});
})。然后(结果=>{
console.log(结果)
});

如评论中所述,
Array.prototype.filter
是同步的,因此不支持承诺。

由于您现在(理论上)可以使用ES6对内置类型进行子类化,因此您应该能够添加自己的异步方法来包装现有的筛选函数:

注意:我已经注释掉了子类化,因为Babel还不支持数组

class AsyncArray/*扩展了Array*/{
建造师(arr){
this.data=arr;//代替数组子类化
}
filterAsync(谓词){
//复制一份数组,在我们完成时它可能会发生变异
const data=Array.from(this.data);
//使用谓词将所有元素转换为承诺数组
//作为承诺
返回Promise.all(data.map((元素,索引)=>谓词(元素,索引,数据)))
//使用承诺的结果调用基础同步筛选器函数
。然后(结果=>{
返回数据。筛选器((元素,索引)=>{
返回结果[索引];
});
});
}
}
//改为创建子类的实例
设arr=newasyncArray([1,2,3,4,5]);
//传递你自己的谓词
arr.filterAsync(异步(元素)=>{
返回新承诺(res=>{
设置超时(()=>{
res(元素>3);
}, 1);
});
})。然后(结果=>{
console.log(结果)
});
这里有一个方法:

let arr = [1,2,3];

function filter(num) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      if( num === 3 ) {
        res(num);
      } else {
        rej();
      }
    }, 1);
  });
}

async function check(num) {
  try {
    await filter(num);
    return true;
  } catch(err) {
    return false;
  }
}

(async function() {
  for( let num of arr ) {
    let res = await check(num);
    if(!res) {
      let index = arr.indexOf(num);
      arr.splice(index, 1);
    }
  }
})();
filterAsync
函数接受一个数组和一个函数,该数组和函数必须返回
true
false
或返回一个解析为
true
false
的承诺,这是您要求的(几乎,我没有重载承诺拒绝,因为我认为这是个坏主意)。如果你对此有任何疑问,请告诉我

var wait=ms=>newpromise(resolve=>setTimeout(resolve,ms));
var filter=num=>wait(1),然后(()=>num==3);
变量filterAsync=(数组,筛选器)=>
Promise.all(array.map(条目=>filter(条目)))
.then(bits=>array.filter(entry=>bits.shift());
filterAsync([1,2,3],过滤器)
.then(results=>console.log(results.length))
.catch(e=>console.error(e));
var console={log:msg=>div.innerHTML+=msg+“
”, 错误:e=>console.log(e+”,“+(e.lineNumber-25))}
这里有一个方法:

let arr = [1,2,3];

function filter(num) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      if( num === 3 ) {
        res(num);
      } else {
        rej();
      }
    }, 1);
  });
}

async function check(num) {
  try {
    await filter(num);
    return true;
  } catch(err) {
    return false;
  }
}

(async function() {
  for( let num of arr ) {
    let res = await check(num);
    if(!res) {
      let index = arr.indexOf(num);
      arr.splice(index, 1);
    }
  }
})();
filterAsync
函数接受一个数组和一个函数,该数组和函数必须返回
true
false
或返回一个解析为
true
false
的承诺,这是您要求的(几乎,我没有重载承诺拒绝,因为我认为这是个坏主意)。如果你对此有任何疑问,请告诉我

var wait=ms=>newpromise(resolve=>setTimeout(resolve,ms));
var filter=num=>wait(1),然后(()=>num==3);
变量filterAsync=(数组,筛选器)=>
Promise.all(array.map(条目=>filter(条目)))
.then(bits=>array.filter(entry=>bits.shift());
filterAsync([1,2,3],过滤器)
.then(results=>console.log(results.length))
.catch(e=>console.error(e));
var console={log:msg=>div.innerHTML+=msg+“
”, 错误:e=>console.log(e+”,“+(e.lineNumber-25))}
承诺救援

var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var filter = num => wait(1).then(() => num == 3);

var filterAsync = (array, filter) =>
  Promise.all(array.map(entry => filter(entry)))
  .then(bits => array.filter(entry => bits.shift()));

filterAsync([1,2,3], filter)
.then(results => console.log(results.length))
.catch(e => console.error(e));

减速器非常棒。“将我的问题减少到我的目标”似乎是一个非常好的策略,适用于任何比简单工具能为您解决的问题更复杂的事情,即过滤一系列无法立即获得的东西。

承诺救援

var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
var filter = num => wait(1).then(() => num == 3);

var filterAsync = (array, filter) =>
  Promise.all(array.map(entry => filter(entry)))
  .then(bits => array.filter(entry => bits.shift()));

filterAsync([1,2,3], filter)
.then(results => console.log(results.length))
.catch(e => console.error(e));

减速器非常棒。“将我的问题减少到我的目标”似乎是一个非常好的策略,适用于任何比简单工具能为您解决的问题更复杂的事情,即过滤一系列无法立即获得的东西。

游戏后期,但由于没有其他人提到它,Bluebird支持Promise.map,这是我对需要aysnc处理的过滤器的选择

[1, 2, 3, 4].reduce((op, n) => {
    return op.then(filteredNs => {
        return new Promise(resolve => {
            setTimeout(() => {
                if (n >= 3) {
                    console.log("Keeping", n);
                    resolve(filteredNs.concat(n))
                } else {
                    console.log("Dropping", n);
                    resolve(filteredNs);
                }
            }, 1000);
        });
    });
}, Promise.resolve([]))
.then(filteredNs => console.log(filteredNs));

游戏进行得很晚,但由于没有其他人提及,蓝鸟支持Promise.map,这是我的过滤器,需要aysnc处理

[1, 2, 3, 4].reduce((op, n) => {
    return op.then(filteredNs => {
        return new Promise(resolve => {
            setTimeout(() => {
                if (n >= 3) {
                    console.log("Keeping", n);
                    resolve(filteredNs.concat(n))
                } else {
                    console.log("Dropping", n);
                    resolve(filteredNs);
                }
            }, 1000);
        });
    });
}, Promise.resolve([]))
.then(filteredNs => console.log(filteredNs));
async function filter(arr, callback) {
  const fail = Symbol()
  return (await Promise.all(arr.map(async item => (await callback(item)) ? item : fail))).filter(i=>i!==fail)
}
async function filterNums(arr) {
  return await arr.reduce(async (res, val) => {
    res = await res
    if (await filter(val)) {
      res.push(val)
    }
    return res
  }, Promise.resolve([]))
}
async function filterNums(arr) {
  return await arr.reduce(async (res, val) => {
    if (await filter(val)) {
      (await res).push(val)
    }
    return res
  }, Promise.resolve([]))
}
function mapAsync<T, U>(array: T[], callbackfn: (value: T, index: number, array: T[]) => Promise<U>): Promise<U[]> {
  return Promise.all(array.map(callbackfn));
}

async function filterAsync<T>(array: T[], callbackfn: (value: T, index: number, array: T[]) => Promise<boolean>): Promise<T[]> {
  const filterMap = await mapAsync(array, callbackfn);
  return array.filter((value, index) => filterMap[index]);
}
function mapAsync(array, callbackfn) {
  return Promise.all(array.map(callbackfn));
}

async function filterAsync(array, callbackfn) {
  const filterMap = await mapAsync(array, callbackfn);
  return array.filter((value, index) => filterMap[index]);
}
function mapAsync(array, callbackfn) {
  return Promise.all(array.map(callbackfn));
}

function filterAsync(array, callbackfn) {
  return mapAsync(array, callbackfn).then(filterMap => {
    return array.filter((value, index) => filterMap[index]);
  });
}
const failSymbol = Symbol();

export async function filterAsync<T>(
  itemsToFilter: T[],
  filterFunction: (item: T) => Promise<boolean>,
): Promise<T[]> {
  const itemsOrFailFlags = await Promise.all(
    itemsToFilter.map(async (item) => {
      const hasPassed = await filterFunction(item);

      return hasPassed ? item : failSymbol;
    }),
  );

  return itemsOrFailFlags.filter(
    (itemOrFailFlag) => itemOrFailFlag !== failSymbol,
  ) as T[];
}
Array.prototype.asyncFilter = async function(f){
    var array = this;
    var booleans = await Promise.all(array.map(f));
    return array.filter((x,i)=>booleans[i])
}
const filterAsync = (asyncPred) => arr => 
  arr.reduce(async (acc,item) => {
    const pass = await asyncPred(item);
    if(pass) (await acc).push(item);
    return acc;
  },[]);
var wait = ms => new Promise(resolve => setTimeout(resolve, ms));
const isOdd = x => wait(1).then(()=>x%2);
(filterAsync(isOdd)([1,2,3,4,4])).then(console.log) // => [1,3]
const filterPromise = (values, fn) => 
    Promise.all(values.map(fn)).then(booleans => values.filter((_, i) => booleans[i]));
export const asyncFilter = async <T>(list: T[], predicate: (t: T) => Promise<boolean>) => {
  const resolvedPredicates = await Promise.all(list.map(predicate));
  return list.filter((item, idx) => resolvedPredicates[idx]);
};