阅读 313

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


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐