一, 背景
大家都知道 nodejs 很快, 为什么会这么快呢, 原因就是 node 采用异步回调的方式来处理需要等待的事件, 使得代码会继续往下执行不用在某个地方等待着. 但是也有一个不好的地方, 当我们有很多回调的时候, 比如这个回调执行完需要去执行下个回调, 然后接着再执行下个回调, 这样就会造成层层嵌套, 代码不清晰, 很容易进入 "回调监狱", 就容易造成下边的例子:
async(1, function(value){
async(value, function(value){
async(value, function(value){
async(value, function(value){
async(value, function(value){
async(value, final);
});
});
});
});
});
这样的写法会让人崩溃, 那么有什么办法可以解决这个问题呢, 或者有其他别的写法吗? 答案是有的, es6 新出的 promise 对象已经 es7 的 async await 都可以解决这个问题, 当然这里先介绍 promise 对象, es7 的 async await 将在后边的文章中分享. 下边将来介绍 Promise 对象.
二, 简介
Promise, 他是一个对象, 是用来处理异步操作的, 可以让我们写异步调用的时候写起来更加优雅, 更加美观便于阅读. 顾名思义为承诺, 许诺的意思, 意思是使用了 Promise 之后他肯定会给我们答复, 无论成功或者失败都会给我们一个答复, 所以我们就不用担心他跑了哈哈. 所以, Promise 有三种状态: pending(进行中),resolved(完成),rejected(失败). 只有异步返回的结构可以改变其状态. 所以, promise 的过程一般只有两种: pending->resolved 或者 pending->rejected.
promise 对象还有一个比较常用的 then 方法, 用来执行回调函数, then 方法接受两个参数, 第一个是成功的 resolved 的回调, 另一个是失败 rejected 的回调, 第二个失败的回调参数可选. 并且 then 方法里也可以返回 promise 对象, 这样就可以链式调用了. 接下来上代码:
var Pro = function (time) {
// 返回一个 Promise 对象
return new Promise(function (resolve, reject) {
console.log('123');
// 模拟接口调用
setTimeout(function () {
// 这里告诉 Promise 成功了, 然后去执行 then 方法的第一个函数
resolve('成功返回');
}, time);
})
};
(function(){
console.log('start');
Pro(3000)
.then(function(data){
console.log(data);
return Pro(5000);})
.then(function(data){
console.log(data);
console.log('end');
})
})();
上边代码中, 定义了一个 Pro 变量, 然后把一个匿名函数赋给他, 函数返回一个 Promise 对象, 然后对象里边接收一个函数, 分别把 resolve 跟 reject 方法当参数传进去, 用 setTimeOut 来模拟异步请求, 当执行 resolve 方法后就会调用 then 方法的一个函数. 结果如下:
三, Promise 的 api
,Promise.resolve()
,Promise.reject()
,Promise.prototype.then()
,Promise.prototype.catch()
,Promise.all() // 所有的都有完成, 相当于 且
,Promise.race() // 完成一个即可, 相当于 或
1,Promise.resolve() 的作用将现有对象转为 Promise 对象 resolvedl;Promise.resolve('test')==new Promise(resolve=>resolve('test'))
2,Promise.reject() 也是返回一个 Promise 对象, 状态为 rejected;
3,then 方法上边已经做介绍, 这里就不再介绍.
4,catch(): 发生错误的回调函数.
5,Promise.all() 适合用于所有的结果都完成了才去执行 then() 成功的操作. 举个例子:
let p1 =new Promise(function(resolve,reject){
resolve(1);
});
let p2 = new Promise(function(resolve,reject){
resolve(2);
});
let p3 = new Promise(function(resolve,reject){
resolve(3);
});
Promise.all([p1, p2, p3]).then(function (results) {
console.log('success:'+results);
}).catch(function(r){
console.log("error");
console.log(r);
});
最后输出:
6,Promise.race() 的作用也是同时执行多个实例, 只要有一个实例改变状态, Promise 就改为那个实例所改变的状态;
四, 例子
var Pro = function () {
// 返回一个 Promise 对象
return new Promise(function (resolve, reject) {
// 模拟接口调用
setTimeout(function () {
resolve(true);
}, 1000);
})
};
var Pro2 = function () {
// 返回一个 Promise 对象
return new Promise(function (resolve, reject) {
// 模拟接口调用
setTimeout(function () {
resolve('Pro2 成功执行');
}, 1000);
})
};
Pro().then(function(data){
var val = data;
console.log(val)
if (val) {
console.log(1111)
return Pro2()
}
}).then(function(data1){
console.log(data1)
})
输出:
这样就可以用 then 方法可以实现链式调用了.
来源: https://www.cnblogs.com/superSmile/p/8406037.html