Promise对象用于表示一个异步操作的最终状态(完成或失败)以及其返回的值。
Promise对象中放的是未来要做的事情,当它被实例化之后就会开始做未来要做的事情,如果成功了做成功的事,失败了就执行失败相应的事情。
同步与异步:
同步任务会阻塞程序执行(alert、for、......)
异步任务不会阻塞程序执行(setTimeout、fs.readFile、......)
一.回调与Promise
1.传统的回调方法 用于请求数据(模拟)
传统的回调方式在解决异步时,会遇到多层回调嵌套的问题。
function f(cb){
setTimeout(function () {
cb && cb();//如果cb存在就调用cb
},1000)
}
f(function(){
console.log(1);
f(function () {
console.log(2);
f(function () {
console.log(3);
//...
})
})
})
2.promise方法 用于请求数据(模拟)
声明一个函数(不用像传统方式传入一个回调函数参数),直接return一个Promise实例,这个Promise实例接收一个resolve的参数,resolve代表成功之后要做的事情。
实例化一个Promise对象之后,它就有了.then()的方法,then方法表示接下来要做的事情,
then方法里的第一个函数就是对应就是resolve,
然后在这个函数中再return一个Promise实例,接下来就可以继续链式调用then方法。
function f(){
return new Promise(resolve =>{
setTimeout(function(){
resolve();//resolve();是成功后执行的,就是等于下面then()里面的函数
},1000);
})
}
f()
.then(function(){
console.log(1);
return f();
})
.then(function(){
console.log(2);
return f();
})
.then(function(){
console.log(3);
return f();
});
Promise 新建后立即执行,然后then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行
二.对比回调与Promise的流程控制
如果then里面有return,则就是链式调用,如果没有return,就是同时执行。
如果不在.then的最后返回一个Promise实例,我们也可以继续.then也是会往后走的,只不过相当于一个啥也没有做的Promise,只是往下走而已。
就相当于还在上一个.then中继续往下写代码,只不过继续.then可以把一段很长的代码分成两段更清晰一点。
三.信任问题
1.信任问题:
传统方法无法保证传递过来的参数只执行一次。
而Promise因为有三种状态,当处于pending状态时传递参数过来决议为resolve成功,状态则不可逆也不可修改了,调用且仅调用一次resolve(),不会产生多次回调多次执行的问题。
所以Promise很好地解决了第三方工具导致的回调多次执行(控制反转)的问题。
2.回调地狱(callback hell):
一层套一层,不容易维护和修改,Promise则可以把异步操作用同步的方式表达出来,而不用多次回调。当传统的嵌套层级需要调换嵌套顺序时,Promise只需要调正先后而不用调整“里外“。
所以Promise解决了一些信用上的问题。
四.错误处理
1.then(resolve,reject)
Promise.then(resolve, reject)都是异步的操作。所以try catch对reject是没有用的。
then方法里可以接收两个参数(都是函数),用逗号隔开。
reject用于处理错误时要执行的操作。
resolve(), reject()中都只能传递一个参数,哪怕写了第二参数,也是接收不到的。
function f(val){
return new Promise((resolve,reject)=>{
if(val){
resolve({
name:'小明'});//只能传递一个参数 resolve({name:'小明'