先说需求,根据数组中的ID值,对每个ID发送请求,获取数据进行操作。

首先肯定考虑用forEach 或者 map对数组进行遍历,然后根据值进行操作,但是请求是个异步操作,forEach又是一个同步操作,等同于同时发出多个异步请求,并不能确定具体返回的数据是哪个请求。(我这里的返回数据中有ID值,可以根据ID查找,这不就是太low了嘛,每次拿到返回来的数据,还得遍历一遍原数组才行)

那么我们如何才能做到即遍历数组又发送请求,同时根据返回值进行操作呐。

解释几点:(不想看的人直接跳结果)

async函数:返回一个promise对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到触发的异步操作完成,再接着执行函数体后面的语句。

await会获取promise的成功回调resolve()返回值,并且只能使用在async函数中(这表面这个函数中有异步操作)同时await将异步变成同步,增加了代码逻辑可读性。注意一点,既然是异步promise就有可能会有rejected的结果,所以一般使用try···catch···或者.catch 来处理请求出错

结果:

当需要同时发起多个异步,可以使用promise.all

// const aa = this.testNumArray.map((item) => {

// return this.getFetch(item);

// });

// const bb = Promise.all(aa);

// bb.then((val) => {

// console.log(val, 'bb-result');

// });

这里的getFetch就是发送的异步请求;

如果后一步的异步请求需要依赖于前一步的数据,即当一个异步请求完结后拿到数据才可以继续发送下一个请求,可以将for of和async/await结合使用

foo = async (array: any) => {

for (let i of array) {

const item = await this.getFetch(i);

console.log(item);

}

};

注意await这里等到的值,一定是一个promise对象(虽然他也可以处理非promise对象,同样可以作为resolve()的值进行输出)

这里解释一下,为何forEach是没有作用的,forEach的第一个参数是一个函数,他的源码中并没有对可遍历对象的异步进行处理,所以他是一个即时操作的回调函数,并不能达到我们异步的需求。

参考网址https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#polyfill

源码:

// Production steps of ECMA-262, Edition 5, 15.4.4.18

// Reference: http://es5.github.io/#x15.4.4.18

if (!Array.prototype.forEach) {

Array.prototype.forEach = function(callback, thisArg) {

var T, k;

if (this == null) {
throw new TypeError(' this is null or not defined');
} // 1. Let O be the result of calling toObject() passing the
// |this| value as the argument.
var O = Object(this); // 2. Let lenValue be the result of calling the Get() internal
// method of O with the argument "length".
// 3. Let len be toUint32(lenValue).
var len = O.length >>> 0; // 4. If isCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function');
} // 5. If thisArg was supplied, let T be thisArg; else let
// T be undefined.
if (arguments.length > 1) {
T = thisArg;
} // 6. Let k be 0
k = 0; // 7. Repeat, while k < len
while (k < len) { var kValue; // a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the HasProperty
// internal method of O with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
if (k in O) { // i. Let kValue be the result of calling the Get internal
// method of O with argument Pk.
kValue = O[k]; // ii. Call the Call internal method of callback with T as
// the this value and argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined

};

}

这里看不懂没有关系,记住一点,红色的代码就是直接执行回调函数。

同时,人家官方都说了:如果使用 promise 或 async 函数作为 forEach() 等类似方法的 callback 参数,最好对造成的执行顺序影响多加考虑,否则容易出现错误

let ratings = [5, 4, 5];

let sum = 0;

let sumFunction = async function (a, b) {

return a + b;

}

ratings.forEach(async function(rating) {

sum = await sumFunction(sum, rating);

})

console.log(sum);

// Expected output: 14

// Actual output: 0

那么问题来了,既然forEach不行,那么for ··· of 为何可以呐?难道for ··· of比较牛逼嘛?

那话如果这么说,for ··· of真滴比较牛逼,因为for循环内置的是一个迭代器,通过Symbol.iterator对可迭代对象的循环。

这里就有一个面试常问到的地方,就是for···of和for···in有什么区别?

当然是遍历的值不同了(of:键值对,in:key值),还有原理实现上的不同,for···of只能对可迭代对象进行遍历循环。for···of可以视为一个迭代器,那么他也有迭代器能终止迭代的属性(break throw continue return)

注意:

  1. 在es6中Object是被认为不可迭代的对象,不能用for···of来循环。
  2. for ···in会遍历所操作对象的所有可枚举属性,包括原型上的属性和方法。

关于在forEach中使用await的问题的更多相关文章

  1. 聊一聊C# 8.0中的await foreach

    AsyncStreamsInCShaper8.0 很开心今天能与大家一起聊聊C# 8.0中的新特性-Async Streams,一般人通常看到这个词表情是这样. 简单说,其实就是C# 8.0中支持aw ...

  2. C#8.0中的 await foreach

    AsyncStreamsInCShaper 8.0 C# 8.0中支持异步返回枚举类型async Task<IEnumerable<T>> sync Streams这个功能已经 ...

  3. C#中async/await中的异常处理

    在同步编程中,一旦出现错误就会抛出异常,我们可以使用try-catch来捕捉异常,而未被捕获的异常则会不断向上传递,形成一个简单而统一的错误处理机制.不过对于异步编程来说,异常处理一直是件麻烦的事情, ...

  4. 关于C#中async/await中的异常处理(下)-(转载)

    上一篇文章里我们讨论了某些async/await的用法中出现遗漏异常的情况,并且谈到该如何使用WhenAll辅助方法来避免这种情况.WhenAll辅助方法将会汇总一系列的任务对象,一旦其中某个出错,则 ...

  5. 小心C# 5.0 中的await and async模式造成的死锁

    平时在使用C# 5.0中的await and async关键字的时候总是没注意,直到今天在调试一个ASP.NET项目时,发现在调用一个声明为async的方法后,程序老是莫名其妙的被卡住,就算声明为as ...

  6. C#实现在foreach中删除集合中的元素

    List<string> str = new List<string>(); str.Add( "zs"); str.Add("ls") ...

  7. C# 6.0:在catch和finally中使用await

    Asyn方法是一个现在很常用的方法,当使用async和await时,你或许曾有这样的经历,就是你想要在catch块或finally块中使用它们,比如当出现一个exception而你希望将日志记在文件或 ...

  8. php在foreach中使用引用赋值&可能遇到的问题(转)

    楼主在写项目的时候,由于初涉PHP的赋值引用操作,觉得这个功能非常强大,用时一时爽,没有深入了解过其中的原理,导致了一些当时觉得不可思议的BUG,废话不都说,我举个例子详细的描述一下这个问题. 代码: ...

  9. 关于C#中async/await中的异常处理(上)-(转载)

    在同步编程中,一旦出现错误就会抛出异常,我们可以使用try…catch来捕捉异常,而未被捕获的异常则会不断向上传递,形成一个简单而统一的错误处理机制.不过对于异步编程来说,异常处理一直是件麻烦的事情, ...

随机推荐

  1. OAuth 2.0 All In One

    OAuth 2.0 All In One 授权类型 授权代码 隐式 密码凭证 客户端凭证 授权码 授权码授予类型要求用户向提供者进行身份验证-然后将授权码发送回客户端应用程序,提取并与提供者交换以获取 ...

  2. ESLint & .eslintignore

    ESLint & .eslintignore https://stackoverflow.com/questions/42250257/disable-eslint-rules-for-fol ...

  3. H.265 & H.264

    H.265 & H.264 HEVC (H.265) vs. AVC (H.264) https://en.wikipedia.org/wiki/High_Efficiency_Video_C ...

  4. 「NGK每日快讯」12.4日NGK公链第31期官方快讯!

  5. [转]自动驾驶平台Apollo 2.5环境搭建

    原文地址:https://blog.csdn.net/jinzhuojun/article/details/80210180,转载主要方便随时查阅,如有版权要求,请及时联系. 我们知道,自动驾驶在学界 ...

  6. 为什么ConcurrentHashMap,HashTable不支持key,value为null?

    ConcurrentHashmap.HashMap和Hashtable都是key-value存储结构,但他们有一个不同点是 ConcurrentHashmap.Hashtable不支持key或者val ...

  7. k8s v1.18.2 centos7 下环境搭建

    准备 服务器:3台机器--1台主.2台工作节点,可以使用virtualbox 搭建虚拟机 主机名 centos version ip docker version flannel version 主机 ...

  8. ClickHouse源码笔记4:FilterBlockInputStream, 探寻where,having的实现

    书接上文,本篇继续分享ClickHouse源码中一个重要的流,FilterBlockInputStream的实现,重点在于分析Clickhouse是如何在执行引擎实现向量化的Filter操作符,而利用 ...

  9. STL栈

    stack的基本操作有: 1.入栈:如s.push(x); 2.出栈:如s.pop(). 注意:出栈操作只是删除栈顶的元素,并不返回该元素. 3.访问栈顶:如s.top(); 4.判断栈空:如s.em ...

  10. 100道Java高频面试题(阿里面试官整理)

    我分享文章的时候,有个读者回复说他去年就关注了我的微信公众号,打算看完我的所有文章,然后去面试,结果我后来很长时间不更新了...所以为了弥补一直等我的娃儿们,给大家的金三银四准备了100道花时间准备的 ...