参考:https://segmentfault.com/a/1190000007032448
https://www.jianshu.com/p/59236e9f3598
在javascript中所有的代码都是单线程执行的,因为这个原因,导致javascript的所有网络操作和浏览器事件都是异步执行的。异步执行可以用回调函数的方式来实现。也可以用promise来实现。
比如,用函数回调的方式现实。
function callback(){console.log('Done');}
console.log('before setTimeout()');
setTimeout(callback,1000);// 1秒钟后调用callback函数console.log('after setTimeout()');
由此可知,异步操作是再将来的某个时间节点触发一个函数的调用。常用的ajax就是一个典型的异步操作。
而Promise对象也是用于异步操作,它表示一个尚未完成且预计在未来完成的异步操作。
有了函数回调为什么还要用promise呢,Promise的真正强大之处在于它的多重链式调用,可以避免层层嵌套回调。比如:
request('test1.html', '', function(data1) {
console.log('第一次请求成功, 这是返回的数据:', data1);
request('test2.html', data1, function (data2) {
console.log('第二次请求成功, 这是返回的数据:', data2);
request('test3.html', data2, function (data3) {
console.log('第三次请求成功, 这是返回的数据:', data3);
//request... 继续请求
}, function(error3) {
console.log('第三次请求失败, 这是失败信息:', error3);
});
}, function(error2) {
console.log('第二次请求失败, 这是失败信息:', error2);
});
}, function(error1) {
console.log('第一次请求失败, 这是失败信息:', error1);
});
以上出现了多层回调嵌套,有种晕头转向的感觉。这也就是我们常说的厄运回调金字塔(Pyramid of Doom),编程体验十分不好。而使用Promise,我们就可以利用then进行「链式回调」,将异步操作以同步操作的流程表示出来。
sendRequest('test1.html', '').then(function(data1) {
console.log('第一次请求成功, 这是返回的数据:', data1);
return sendRequest('test2.html', data1);
}).then(function(data2) {
console.log('第二次请求成功, 这是返回的数据:', data2);
return sendRequest('test3.html', data2);
}).then(function(data3) {
console.log('第三次请求成功, 这是返回的数据:', data3);
}).catch(function(error) {
//用catch捕捉前面的错误
console.log('sorry, 请求失败了, 这是失败信息:', error);
});
这样就很明晰了。
Promise的基本用法
它有以下三种状态:
pending:初始值,不是fulfilled,也不是rejected
fulfilled:代表操作成功
rejected:代表操作失败
Promise有两种状态改变的方式,既可以从pending转变为fulfilled,也可以从pending转变为rejected。一旦状态改变,就「凝固」了,会一直保持这个状态,不会再发生变化。当状态发生变化,promise.then绑定的函数就会被调用。
Promise接受一个「函数」作为参数,该函数的两个参数分别是resolve和reject。这两个函数就是「回调函数」
resolve参数的作用:在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject参数的作用:在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

如果异步操作获得了我们想要的结果,那我们将手动调用resolve函数,在then的第一个作为参数的匿名函数中可以获取数据,如果我们得到了错误的结果,调用reject函数,在then函数的第二个作为参数的匿名函数中获取错误处理数据。 这样,一个次完整的Promise调用就结束了。
网友评论