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的主要内容,如果未能解决你的问题,请参考以下文章