Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Day121:说一下 在 map 中和 for 中调用异步函数的区别 #934

Open
Genzhen opened this issue Aug 19, 2020 · 1 comment
Open

Day121:说一下 在 map 中和 for 中调用异步函数的区别 #934

Genzhen opened this issue Aug 19, 2020 · 1 comment
Labels
JavaScript teach_tag

Comments

@Genzhen
Copy link
Collaborator

Genzhen commented Aug 19, 2020

每日一题会在下午四点在交流群集中讨论,五点 Github、交流群同步更新答案

扫描下方二维码,收藏关注,及时获取答案以及详细解析,同时可解锁800+道前端面试题。

@Genzhen Genzhen added the JavaScript teach_tag label Aug 19, 2020
@Genzhen
Copy link
Collaborator Author

Genzhen commented Aug 20, 2020

map & for

  • map 会先把执行同步操作执行完,就返回,之后再一次一次的执行异步任务
  • for 是等待异步返回结果后再进入下一次循环

map

const arr = [1, 2, 3, 4, 5];
function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("data");
    }, 1000);
  });
}

(async () => {
  const result = arr.map(async () => {
    console.log("start");
    const data = await getData();
    console.log(data);
    return data;
  });
  console.log(result);
})();

// 5 start -> 遍历每一项开始
// (5) [Promise, Promise, Promise, Promise, Promise] -> 返回的结果
// 5 data -> 遍历每一项异步执行返回的结果

分析

map 函数的原理是:

  1. 循环数组,把数组每一项的值,传给回调函数
  2. 将回调函数处理后的结果 push 到一个新的数组
  3. 返回新数组

map 函数函数是同步执行的,循环每一项时,到给新数组值都是同步操作。

代码执行结果:

map 不会等到回调函数的异步函数返回结果,就会进入下一次循环。

执行完同步操作之后,就会返回结果,所以 map 返回的值都是 Promise

解决问题

  • 使用 for、for..of 代替

简单实现一个

// 获取数据接口
function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("data");
    }, 1000);
  });
}
// 异步的map
async function selfMap(arr, fn) {
  let result = [];
  for (let i = 0, len = arr.length; i < len; i++) {
    const item = await fn(arr[i], i);
    result.push(item);
  }
  return result;
}
// 调用
(async () => {
  const res = await selfMap([1, 2, 3, 4, 5], async (item, i) => {
    const data = await getData();
    return `${item}_${data}`;
  });
  console.log(res, "res");
})();
// ["1_data", "2_data", "3_data", "4_data", "5_data"] "res"

for

function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve("data");
    }, 1000);
  });
}

(async () => {
  for (let i = 0, len = arr.length; i < len; i++) {
    console.log(i);
    const data = await getData();
    console.log(data);
  }
})();

// 0
// data
// 1
// data
// 2
// data
// 3
// data
// 4
// data

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JavaScript teach_tag
Projects
None yet
Development

No branches or pull requests

1 participant