• javascript的异步编程解决方案收集


    缘起

    没理解js异步的同学看下面的例子:

    for (var i = 0; i < 5; i++) {
      //模拟一个异步操作 setTimeout(()
    => { console.log(i); }, 1000); }

    我们想要的结果是:0,1,2,3,4

    结果却出乎意料:5,5,5,5,5

    分析

    js的特点就是单线程异步非堵塞。需要好好理解这句话:js对于异步操作,不会停下来等待上一个异步操作完成,才进行下一个异步操作。

    如果要达到顺序执行,只能用回调:也就是上一个异步操作完成时,再调用下一个异步操作。

    要是如上面的循环,要如何操作呢?

    解决方法1

    通过调用自身解决循环的回调嵌套问题

    function sync(i) {
      setTimeout(() => {
        if (i < 5){
          console.log(i);
          i++;
          sync(i);
        }
      }, 1000);
    }
    
    sync(0)

    解决方法2

    使用await/async

    优点:直观,符合同步编程思维。其实本质还是异步回调

    缺点:大部分浏览器下载还不支持。需要配合Promise使用,需要写成两个函数

    服务器端node.js支持。以下代码在最新版chrome浏览器中可以运行:

    const f = (i) => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(i);
        }, 1000);
      });
    };
    
    const testAsync = async () => {
      for (var i = 0; i < 5; i++) {
        const t = await f(i);
        console.log(t);
      }
    };
    
    testAsync();

    解决方法3

    使用co

    function* useco(){
      for(var i=0; i<5; i++){
        yield new Promise((resolve, reject) => {
            setTimeout(() => {
              resolve(i);
              console.log(i);
            }, 1000);
        });
      }
    }
    
    co(useco);

    依赖于上一个异步操作的结果,进行下一个异步操作:

    function* useco() {
      var x=0;
      for (var i = 0; i < 5; i++) {
        x= yield new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve(x+i);
          }, 1000);
        });
        console.log(x);
      }
    }

    co(useco).then(() => {
       console.log('执行完毕');
    })
     

    co还是很强大的。

    解决方法4

    等待补充...

  • 相关阅读:
    HDU 3339 In Action 最短路+01背包
    hash与map的区别联系应用(转)
    POJ
    欧几里德与扩展欧几里德算法(转)
    POJ
    第三届蓝桥杯C++B组省赛
    第四届蓝桥杯C++B组省赛
    第五届蓝桥杯C++B组省赛
    第六届蓝桥杯C++B组省赛
    线段树为什么要开4倍空间
  • 原文地址:https://www.cnblogs.com/slmk/p/6684206.html
Copyright © 2020-2023  润新知