今天看了好几位大牛的文章,整理和记录下对promise的认识。 方便大家一起学习~
Promise是异步编程的一种解决方案,它有三种状态,分别是pending-进行中、resolved-已完成、rejected-已失败当Promise的状态又pending转变为resolved或rejected时,(承诺执行)会执行相应的方法,并且状态一旦改变,就无法再次改变状态,这也是它名字promise-承诺的由来.
JS
就是操作对象上的属性和方法,对于一个对象,想要了解,我们可以直接从其身上的属性和方法入手;直接使用console.dir(对象)
打印出来
从上面打印出来的属性和方法,可以看到Promise
是一个构造函数,有属于自己私有的all,reject,resolve,rece
等方法,也有原型上面的,属于实例对象调用的方法then,catch
在JavaScript的世界中,所有代码都是单线程执行的。由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。异步执行可以用回调函数实现:
function callback() {
console.log('执行完毕');
}
console.log('before setTimeout()');
setTimeout(callback, 1000); // 1秒钟后调用callback函数,模拟网络请求
console.log('after setTimeout()');
function test(resolve, reject) {
var timeOut = Math.random() * 2;
console.log('set timeout to: ' + timeOut + ' seconds.');
setTimeout(function () {
if (timeOut < 1) {
console.log('call resolve()...');
resolve('200 OK');
}
else {
console.log('call reject()...');
reject('timeout in ' + timeOut + ' seconds.');
}
}, timeOut * 1000);
}
var p1 = new Promise(test);
var p2 = p1.then(function (result) {
console.log('成功:' + result);
});
var p3 = p2.catch(function (reason) {
console.log('失败:' + reason);
});
变量p1
是一个Promise对象,它负责执行test
函数。由于test
函数在内部是异步执行的,当test
函数执行成功时,我们告诉Promise对象:
// 如果成功,执行这个函数:
p1.then(function (result) {
console.log('成功:' + result);
});
当test
函数执行失败时,我们告诉Promise对象:
p2.catch(function (reason) {
console.log('失败:' + reason);
});
Promise对象可以串联起来,所以上述代码可以简化为:
new Promise(test).then(function (result) {
console.log('成功:' + result);
}).catch(function (reason) {
console.log('失败:' + reason);
});
可见Promise最大的好处是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了。
链式操作 ----- promise 的 all 与 race 用法和区别
Promise
对于多层回调,可以简化其写法,使得更加的语义化;但是Promise
的精髓在于其链式操作,传递状态
,维护状态的方式使得回调函数能够及时的调用
all
方法的使用
Promise
对象上的方法,实例不能使用,只能这个对象使用,这个方法通过了并行执行异步
操作的能力,并且在所有的异步操作完成后才执行回调
Promise
.all([runAsync1(),runAsync2(),runAsync3()])
.then(function(results){
console.log(results);
});
Promise.all
来执行前面的三个异步的函数,all()
接收一个数组参数,里面的执行最终都返回Promise
对象,只有等三个异步操作都执行完成后才会进入到then
里面,all
会把所有的异步操作的结果放在一个数组中传给then
,就是上面的results
race
的用法这个也是
Promise
类上面的私有方法,对于前面的all
方法来说是:谁的程序执行的慢,就等谁执行完才回调。但是对于race
来说:谁的程序执行的快,就以它为标准调用回调函数,其用法基本上是一样的,把上面runAsync1
函数的延迟改为1秒
Promise
.race([runAsync1(),runAsync2(),runAsync3()])
.then(function(results){
console.log(results);
});
这三个 异步操作同样是并行执行的,但是等到1秒后,runAsync1
已经执行完毕,于是then
接受到了执行完毕的回调,输出回调结果;与此同时,runAsyn2
和runAsyn3
也继续执行,输出了执行的结果,但是不能回调then
方法。
参考链接:
https://www.jianshu.com/p/43f948051d65
https://www.jianshu.com/p/c98eb98bd00c
https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/0014345008539155e93fc16046d4bb7854943814c4f9dc2000#0