es6 中的异步编程 promise

Posted 猎聘技术中心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了es6 中的异步编程 promise相关的知识,希望对你有一定的参考价值。

promise 的用处在于把多层回调的嵌套, 铺平。



下面是一个异步回调的例子:


var func1 = function(callback){

  console.log('func1');

  setTimeout(callback, 1000);

};

var func2 = function(callback){

  console.log('func2');

  setTimeout(callback, 1000);

};

 

func1(function(){

  func2(function(){

    console.log('end');

  });

});


这段代码最终实现的效果就是,一开始输出 func1 然后每隔一秒分别输出 func2,end


代码分析


要理解上面的代码段,首先要理解回调,回调是js编程非常重要的部分。


要理解回调,首先要理解一个函数可以做为参数来传递,回调一般是通过参数传递给另一个方法的


var f1 = function(){console.log('f1');};

var f2 = function(callback){

  $('.box').on('click', function(){

    callback();

  });

};

f2(f1);


那么上述代码中,把 f1 做为参数传给了 f2,那么 f2 中就有了 f1 这个函数,并把它命名为 callback,然后通过 callback() 来调用,那么这个 callback 就是一个回调函数。


你在绑事件时传的所有匿名函数,也是回调。


那么在理解了这些后,上面的代码就不难理解了。


但如果嵌套过多,就会看起来比较复杂


func1(function(){

  func2(function(){

    func3(function(){

      func4(function(){

 

      });

    });

  });

});


类似于这样的循环嵌套,通过 promise 实现:


var func1 = function(){

  console.log('func1');

  return new Promise(function(resolve, reject){

    setTimeout(resolve, 1000);

  });

};

var func2 = function(){

  console.log('func2');

  return new Promise(function(resolve, reject){

    setTimeout(resolve, 1000);

  });

};

func1().then(function(){

  return func2();

}).then(function(){

  console.log('end');

});


下面可以简写为:


func1().then(func2).then(()=>console.log('end'));


代码分析


之所以要把 new Promise 放在一个函数里面,是因为 new Promise 是一个会被马上执行的类,跟 new Date() 类似,一但 new 了,就会马上执行。


var func1 = function(){

  console.log('func1');

  return new Promise(function(resolve, reject){

    setTimeout(resolve, 1000);

  });

};


理解这段代码前,我们先深入了解一下 reutrn。


var fun1 = function(){};

fun1 = fun1();

console.log(fun1);    //undefined

var fun1 = function(){ return 1; };

fun1 = fun1();

console.log(fun1);   //1


简单说就是一个函数调用完毕可以通过 return 返回一个值,当没有 return 时,会默认 return undefined;


return 可以返回多种形式,字符串、数字、数组、对象、类、函数等等。


return 'string';

return 100;

return [];

return {};

return new class();

return function(){};    //重要


理解 return 能返回一个函数非常重要,也是我认为初学者有点难理解的地方。


var fun1 = function(){

  console.log('start');

  return function(){

    console.log('end');

  }

};

var f1 = fun1();      //会输出start

f1();                 //会输出end


在调用 fun1 时,打印了 start,然后通过 return 返回了一个匿名函数,并把这个函数赋给了 f1。但这个时候并没有执行这个函数。直到通过 f1() 调用后,打印 end。


那么再来看这段代码


var func1 = function(){

  console.log('func1');

  return new Promise(function(resolve, reject){

    setTimeout(resolve, 1000);

  });

};


当我调用 func1 时,进入到 func1 函数内部,首先打印 func1,然后会返回一个 Promise 对象。


Promise 对象拥有 then、catch 方法。


调用 resolve() 会走 then 方法


调用 reject() 会走 catch 方法


如果 Promise 里面的代码报错出会走 catch 方法


那么 func1().then() 的意思就是: 调用了 func1 这个函数,返回了一个 Promise 对象,这个时候就可以通过 .then() 获取通过调用 resolve() 后执行的结果。


再来看这段代码


func1().then(function(){

  return func2();

}).then();


我们往 then 方法里传了一个匿名函数,它会在上面调用 resolve() 时执行,执行后,会返回一个 func2 函数调用 func2 会返回一个 Promise 对象,这样经过层层返回,最后会返回给 then 一个 promise 对象,所以后面可以继续 .then()。


通过 jquery 的队列,也可以实现同样的效果


//定义一个列队方法

function runQueue(arr){

  var name = 'queue'+new Date().getTime();

  return $(document).queue(name, arr).dequeue(name);

}

//其中next的意思是进行数组的下一项,由jquery调用数组里的方法时传入。

var func1 = function(next){

  console.log('func1');

  setTimeout(next, 1000);

};

var func2 = function(next){

  console.log('func2');

  setTimeout(next, 1000);

};

runQueue([func1, func2]);


自己实现一个类似 jquery 的队列的效果


var func1 = function(next){

  console.log('func1');

  setTimeout(next, 1000);

};

var func2 = function(next){

  console.log('func2');

  setTimeout(next, 1000);

};

function myQueue(arr){

  function f1(){

    var f = arr.shift();

    f && f(f1);

  }

  return f1();

}

myQueue([func1, func2, func1, func2, func1, func2]);





以上是关于es6 中的异步编程 promise的主要内容,如果未能解决你的问题,请参考以下文章

ES6:Promise与异步编程

ES6:Promise与异步编程

前端ES6异步编程技术——Promise使用

《深入理解ES6》笔记—— Promise与异步编程

es6异步编程 Promise 讲解 --------各个优点缺点总结

JS异步编程,回调函数与promise