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