vue await‘ expressions are only allowed within async functions and at the top le

2,439 阅读1分钟

写vue就很少用for循环 今天有个请求遇到了,结果在forEach循环里一直无法使用await方法,因为forEach只支持同步代码

报错:

async aaa() {
  files.forEach((item, index)=>{
    try{
        await this.upload(item)
    }catche(err){
        console.log(err)
    }
    
  })
}

修改:

async aaa() {
  for(let m = 0; m < files.length; m++) {
    try{
        await this.upload(item)    }catche(err){
        console.log(err)
    }
  }
}

或者用 for ... of循环 、 while

MDN上的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
  };
} 

简化之后类似于

    while (index < arr.length) {
      callback(item, index)   //也就是我们传入的回调函数
    }


从上述代码中我们可以发现,forEach 只是简单的执行了下回调函数而已,并不会去处理异步的情况。**并且你在 callback 中即使使用 break 也并不能结束遍历。 使用Promise.all也不行**

for...of 参考 [es6](https://es6.ruanyifeng.com/#docs/iterator#for---of-%E5%BE%AA%E7%8E%AF)

数组原生具备iterator接口(即默认部署了Symbol.iterator属性)``for...of``循环本质上就是调用这个接口产生的遍历器,可以用下面的代码证明。

const arr = ['red', 'green', 'blue'];

for(let v of arr) {
  console.log(v); // red green blue
}


const obj = {};
obj[Symbol.iterator] = arr[Symbol.iterator].bind(arr);

for(let v of obj) {
  console.log(v); // red green blue
}

上面代码中,空对象obj部署了数组arr的Symbol.iterator属性,结果obj的for...of循环,产生了与arr完全一样的结果。

for...of``循环可以代替数组实例的forEach方法。

for..in只遍历对象自身的和继承的可枚举的属性,会返回继承的属性

for...in``循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

let arr = [3, 5, 7];
arr.foo = 'hello';

for (let i in arr) {
  console.log(i); // "0", "1", "2", "foo"
}

for (let i of arr) {
  console.log(i); //  "3", "5", "7"
}

while

async function test() {
  let arr = [3, 2, 1]
  var i=0;
  while(i!==arr.length){
    const res = await fetch(arr[i])
    console.log(res)
    i++;
  }
  console.log('end')
}
 
function fetch(x) {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
   resolve(x)
  }, 500 * x)
 })
}
 
test()

如果 forEach支持async await

arr.myforeach(async v => {
    await fetch(v);
});

Array.prototype.myforeach = async function (fn, context = null) {
    let index = 0;
    let arr = this;
    if (typeof fn !== 'function') {
        throw new TypeError(fn + ' is not a function');
    }
    while (index < arr.length) {
        if (index in arr) {
            try {
                await fn.call(context, arr[index], index, arr);
            } catch (e) {
                console.log(e);
            }
        }
        index ++;
    }
};

参考blog.csdn.net/RaeZhang/ar…

blog.csdn.net/qianyu62004…