Promise 学习笔记(一)
一、异步和同步
我们来举一个生活小例子:
大学室友小明要洗澡,同时小李也要洗澡。由于小李的谦虚就让小明先洗澡了,小李在外面干等着,这期间什么都不干,就干等着,这就像alert,不点确定的话往后的代码就不会执行。这个就是
同步
,会阻塞任务的执行。第二天,小李在小明洗澡之前,和他说“等你洗完澡打电话给我,我先去超市买点东西”,这里就是一个异步
的操作,在等待的期间,可以做自己的事情。
二、什么是Promise?
Promise对象用于表示一个异步操作的最终状态以及其返回的值。
有两个特点:
1.对象的状态不受外界的影响
Pending(进行中)
Fulfilled(已成功)
Rejected(已失败)
只有异步操作结果才能决定当前是哪一种状态,其他操作就无法改变这个状态。
2.一旦状态改变就不会再变
Promise改变只有两种情况
Pending—>Fulfilled
Pending—>Rejected
只有这两种情况发生,状态就不会再改变,这时候就成为Resolved(已定型)
三、什么使用Promise?
- 在实际开发中我们会遇到多层调用,层层嵌套的情况。比如下面代码,可读性和维护性都很差的。当我们修改其中某一部分的代码,就会很麻烦。
function f(cb) {
setTimeout(function() {
cb && cb();
}, 1000);
}
f(function() {
console.log(1);
f(function() {
console.log(2);
f(function() {
console.log(3);
});
});
如果使用 promises 的话,代码就会变得扁平且更可读了。我们可以将 then 的调用不停地串连起来,其中 then 返回的 promise 装载了由调用返回的值。
// 方法 用于请求数据(模拟)
function f() {
return new Promise(resolve => {
setTimeout(function () {
resolve();
}, 1000);
});
}
f()
.then(function () {
console.log(1);
console.log(f());
return f();
})
.then(function () {
console.log(2);
return f();
})
- 而且使用promises 可以更好的捕获异常。通过 reject 方法把 Promise 的状态置为 rejected,这样我们在 then 中就能捕捉到,然后执行“失败”情况的回调。
四、信任问题?
function method(cb) {
// 未按所想的预期执行回调
setTimeout(function() {
// 讲道理应该是现在该调用回调了
cb && cb();
// 但是?? 好像这个库有bug啊 emm 被多调用了一次
cb && cb();
}, 1000);
}
回调函数和Promise的区别:
回调函数不能保证什么时候去调用回调、使用什么方式去调用回调,当然也不能保证只执行一次。这就是信任上的问题。
而Promise一旦被确认成功或失败,就不能再被更改。而Promise调用且仅调用一次resolve(),不会产生回调多次执行的问题。
所以Promise很好地解决了第三方工具导致的回调多次执行(控制反转)的问题。Promise解决了信任上的一些问题。