js中for与map在返回promise时的区别?

遇到一个问题:下面是拿到一个数组返回,通过遍历返回一个值,我之前习惯用map去遍历。

const getCapture=async ()=>{
  let result=await ipcRenderer.invoke('goCapture-event')
  for(const m of result){
    if(m.name==='整个屏幕'){
      let str=m.thumbnail.crop({x:0,y:0,width:1200,height:1170})
      const imgSrc=str.toDataURL()
      return imgSrc
    }
  }
/*
  result.map(m=>{
    if(m.name==='整个屏幕'){
      console.log(m)
     let str=m.thumbnail.crop({x:0,y:0,width:1000,height:1000})
     const imgStr=str.toDataURL()
     return  imgStr
    }
  })
*/
}

这是map的遍历:

result.map(m=>{
    if(m.name==='整个屏幕'){
      console.log(m)
     let str=m.thumbnail.crop({x:0,y:0,width:1000,height:1000})
     const imgStr=str.toDataURL()
     return  imgStr
    }
  })

这样返回的竟然是空,
但是如果用for,就可以正确返回:

for(const m of result){
    if(m.name==='整个屏幕'){
      let str=m.thumbnail.crop({x:0,y:0,width:1200,height:1170})
      const imgSrc=str.toDataURL()
      return imgSrc
    }
  }

js中for和map还有这区别吗?

阅读 1.4k
5 个回答

map的回调函数内部用return语句,返回给了map内部的匿名函数,外层的getCapture函数没有接到,所以返回的是空,修改成这样接收:

//getCapture函数内部
const mappedResult = result.map(m => {
    if (m.name === '整个屏幕') {
      console.log(m)
      let str = m.thumbnail.crop({x: 0, y: 0, width: 1000, height: 1000})
      const imgStr = str.toDataURL()
      return imgStr
    }
    return undefined;
 });
 return mappedResult.find(imgStr => imgStr !== undefined);

跟 Promise 一点儿关系都没有,甚至跟 map() 也没啥关系。这是最基本的 JS 语法问题。

const bar = (callback) => callback();
const foo = () => {
    bar(() => {
        return 1;
    });
}
let ret = foo(); // undefined

/* ----------------- */

const foo = () => {
    for (;;) {
        return 1;
    }
}
let ret = foo(); // 1

看明白了吗?第一种写法里 foo 函数有返回值吗?你说你写了 return,那是 bar 的回调函数里的返回值,foo 函数自己有吗?

你的if里面判断成功了才返回imgSrc ,如果判断不成功呢? 什么都不返回,那不就是空?
js基础不牢固啊,老弟

你这是基础的问题,你上面的getCapture执行后会 return 一个imgSrc,你想要的结果只是result中的一个值,它本身不是数组。我搞不懂你这边为什么要用map去执行,map的结果是返回数组,跟你原本的结果不一致,而且如果你要使用map,代码应该这样写:

const getCapture=async ()=>{
  let result=await ipcRenderer.invoke('goCapture-event')
  return result.map(m=>{
    if(m.name==='整个屏幕'){
      console.log(m)
     let str=m.thumbnail.crop({x:0,y:0,width:1000,height:1000})
     const imgStr=str.toDataURL()
     return imgStr
    }
  })[0] || "";
  }

这样写才能有你上面代码的效果。

给你贴一个map简易的实现原理,我几年前写的,你对map的理解不够。

Array.prototype.myMap = function (fun) {
    const arr = [];
    for (let i = 0; i < this.length; i++) {
        const val = fun.call(this, this[i], i, this)
        arr.push(val);
    }
    return arr;
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题