首页 » 我的课程 » web前端 » 正文

[js]循环内部有异步调用时如何让变量能”同步”保持

   这是一个群学员的提问,之前也有人提问过,因此单独拿出来写篇文章。 

   大概过程是这样:

   function ajax(p) { //这里为了代替ajax行为,譬如axios等货色,处理都是返回promise,不重要,主要体现异步
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(p)
        },200)
    })
 }

    function  test() {
    const arr=[1,2,3,4,5];
    let i=0; //注意这里
    for( i=0;i<arr.length;i++){
        ajax(arr[i]).then((result)=>{
            console.log(i) //重点在这,他想在这里 获得响应结果后,继续获取当前的i
        })
    }
}

  test(); //运行test函数

   问题就来了,由于for循环下面的ajax函数是异步的,因此 最终打印出来的i,一直是5

    原因很简单

   1、主线程哗一下就把循环执行完了,所以i一直加到了5 (注意是5,而不是4,最后一次i++加完后发现不符合循环条件,所以不会继续循环,但是不代表i只加到了4)

   2、ajax 函数是宿主(不管是用 node还是浏览器)开了另外的线程在执行

  所以不管 怎样,ajax的then最终得到的i 都是 5 

  解决这个问题的方法(就不要想着 如何让ajax同步执行,想多了你~~~~)

   1、最简单的方法是使用es7的async /await语法糖 (注意 运行或编译需要babel的支持,不会请自行百度)

      async function  test() {
        const arr=[1,2,3,4,5];
        let i=0;
       for( i=0;i<arr.length;i++){
          let result= await ajax(arr[i]); //这里得到结果
          console.log(i) ; //这里就能输出 0,1,2,3,4
      }
  }

 2、常规方法,调用时再套一个匿名函数即可

     function  test() {
    const arr=[1,2,3,4,5];
    let i=0;
    for( i=0;i<arr.length;i++){
        (function(param,index){
            ajax(param).then((result)=>{
                console.log(index)
            })
        }(arr[i],i))

    }
}


 async/awit 在react课程里讲过,戳http://www.jtthink.com/course/52

发表评论