JavaScript异步编程简单探索

2017-08-22  本文已影响19人  进击的程序茗

关于js异步编程前世今生,从回调函数到事件监听到发布订阅到Promise,网上有很多解释,所以本文仅做对于异步编程的简单记录详情可见其它blog:
javascript异步编程的前世今生,从onclick到await/async
阮一峰es6入门async 函数

场景前言:

在封装判断是否为wifi组件时,其中用到了一个异步操作,若想拿到结果需要通过回调函数的方式,因此考虑到了是否可以不用回调的方式,产生了这篇文章,模拟场景代码如下:

var re = 2;
function time(){
    setTimeout(function(){
        re = 3;
        },300);
    console.log(re);//output 2
}
 time();

在如上代码中settimeout执行了等待300ms的异步操作,所以输出的re值并没有被改变。如果希望最后拿到的值为执行300ms之后的值,尝试方式如下:

回调函数:

无论是ajax还是事件处理,在异步操作中最常用的函数就是回调函数,上述代码改成回调方式如下:

        var re = 2;
        function time(cb){
            setTimeout(function(){
                re = 3;
                cb(re)
            },300);
        }
        time(function(data){
            console.log(data)//output 3
        });

这种回调函数是比较普遍的写法,但是当回调层数多了之后,就会变成函数中层层嵌套的cb,看着比较乱,而且当时的代码场景中只有一个异步场景,并不想启用回调函数。所以又尝试了promise

Promise:

promise用来传递异步操作的消息,可为异步操作的结果提供统一的api,也就是说Promise优化了代码的回调方式,使代码更易维护,并没有对异步操作进行任何改变,将上述代码更改成如下方式:

    var re = 2;
    function test(){
        function time(){
            return new Promise(function(resolve, reject){
                        setTimeout(function(){
                    re = 3;
                    resolve(re);
                },300);
            })
        }
        time().then(function(data){
            console.log(data)//output 3
        })
        console.log(re)//output  2
    };
    test();

从上述结果可以看到,我执行得到的结果仍然是2,Promise并没有改变异步的操作。如此又尝试了async/await方式.

Async/Await

async函数返回一个Promise对象,可以使用then方法添加回调函数,函数执行时,遇到await就会先返回,等到触发的异步操作完成,再执行函数体后面的语句,await后面的函数应该是promise对象的实例,从下面代码看出在test函数里面打印出来的re值是经过异步函数更改过的,但是我们如果return re的值,打印test函数仍然不能得到re的值,因为async返回的是promise对象,所以test函数还是要通过调用then方法获得返回值。

    var re = 2;
    async function test(){
      function time(){
        return new Promise(function(resolve, reject){
          setTimeout(function(){
            re = 3;
            resolve();
          },300);
        });
      }
      await time()
      console.log(re);//output 3
      return re;
    }
    test().then(status=>console.log(status)) //output 3

进行到这里发现虽然最后async可以等待异步执行结束再执行其后的函数体,但如果从获得返回值上来说,仍是要走回调函数的,我最开始希望可以通过最后输出var result = test()这样的方式拿到异步操作后的re其实并没有实现,不知道有没有其它的方法,还请告知。如文中有错误还请指出。

个人博客:
进击的程序茗

上一篇 下一篇

猜你喜欢

热点阅读