js中filter与map的异步回调
filter
let newArray = arr.filter(callback(element[, index[, array])[, thisArg])复制代码
callback
调用filter的数组本身
当前正在被处理元素在数组中的索引
数组中当前正在处理的元素
用来测试数组的每个元素的函数。返回
true
表示该元素通过测试,保留该元素,false
则不保留接收以下三个参数
element
index
可选array
可选thisArg
可选当传入此值时,callback函数内部的this绑定thisArg
描述
filter对每个元素调用一次callback,然后对callback的返回值进行筛选,留下 !!returnValue === true
的元素,生成新的数组,void返回值为undefined
对于thisArg
当callback是箭头函数时无法绑定thisArg
,是function声明时可以绑定。箭头函数没有this,绑定不了
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; const obj = { name: '小明', age: 8 } const newArray = array.filter(function(item) { return item === this.age }, obj) console.log(newArray) // [ 8 ]复制代码
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9]; const obj = { name: '小明', age: 8 } const newArray = array.filter((item) => { console.log(this) return item === this.age }, obj) console.log(newArray) // 空数组 //{} //{} //{} //{} //{} //{} //{} //{} //{} //[]复制代码
手动实现
const newFilter = (array, callback, thisArg = {}) => { if (!/^[Ff]unction$/.test(typeof callback)) { console.log('这不是一个函数'); throw new Error(); } if (!array) return []; let newObject = {...thisArg}; newObject.filterr = function (array2) { let newArray = []; for (let index in array2) { let returnValue = callback(array2[index], index, array2); if (!!returnValue) newArray.push(array2[index]) } return newArray } return newObject.filterr(array) } let array = newFilter([1, 2, 3, 4, 5], (item) => { return item > 3 }, { name: '小明'}) console.log(array) // [4, 5]复制代码
搞得这么复杂是想将箭头函数的this指向解决,但是最终还是没有解决
map
map与filter原理一致,对数组中每一个元素调用一下callback,传入元素经过callback后返回出新的元素,最终生成一个新的数组
手动实现
function newMap (array, callback, thisArg = {}) { if (!/^[Ff]unction$/.test(typeof callback)) { console.log('这不是一个函数'); throw new Error(); } if (!array) return []; let newArray = []; for (let index in array) { let returnValue = callback.call(thisArg, array[index], index, array); newArray.push(returnValue) } return newArray } let array = newMap([1, 2, 3, 4, 5], function (item) { return item + 3 }, { name: '小明'}) console.log(array)复制代码
聊一聊 async 修饰的回调函数
为什么filter的被async修饰过的回调函数无法生效
首先
arr = [1, 2, 3]复制代码
然后arr
调用filter
arr.filter(async (item) => item >=2 )复制代码
因为async修饰的函数返回值只会是一个promise
如果没有被async修饰,原本应该是这样的:
let newArr = (return [false, true, true]) // 小括号表示函数及函数体,return 筛选出数组中是true的,最后结果是[2, 3]复制代码
但是被async修饰之后,结果是这样的
let newArr = (return [Promise<pending>, Promise<pending>, Promise<pending>]) // 因为没有具体的布尔值,会对元素进行两次取反操作,即!!Propise<pending>,结果为true // 于是结果就是 [1, 2, 3],与原数组一致复制代码
那为什么map可以使用异步函数作为回调呢
因为map是映射不是过滤,他不需要对回调函数的返回值进行处理,是啥样就是啥样给出去
arr.map(async (item) => item + 2 )复制代码
之前的步骤是一样的,到了读取返回值的时候,是这样的
let newArr = (return [Promise<pending>, Promise<pending>, Promise<pending>]) // newArr 就是一个元素全为Promise的数组 // newArr == [Promise<pending>, Promise<pending>, Promise<pending>]复制代码
在newArr前使用一个先使用promise.all()同时对每一个元素同时进行处理(有点像归一化?),只剩一个promise,然后在Promise.all前使用一个await,等待最后的这个Promise执行结束
let newArr = await Promise.all(return [Promise<1>, Promise<2>, Promise<3>]) // newArr = [3, 4, 5]
作者:之晏
链接:https://juejin.cn/post/7031074489341313060