闽公网安备 35020302035485号
// 堆代码 duidaima.com
getUser(function(user, err) {
if (err) {
console.log(err);
return;
}
console.log(user);
});
但是这种处理异步操作的方式有一个明显的缺点,就是代码嵌套太深,导致可读性非常差。而 Promise 可以简单而优雅的解决这个问题。我们可以简单地使用 Promise 来封装异步操作:getUser()
.then(function(user) {
console.log(user);
})
.catch(function(err) {
console.log(err);
});
function getUser() {
return new Promise(function(resolve, reject) {
// 异步操作
if (success) {
resolve(user);
} else {
reject(err);
}
});
}
上述代码相比于回调函数要清晰简单很多。如果出错,也可以通过 catch 捕捉到错误。Promise.all([getUser1(), getUser2(), getUser3()])
.then(function(results) {
console.log(results);
});
function getUser1() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(1);
}, 500);
});
}
function getUser2() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(2);
}, 500);
});
}
function getUser3() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
reject(3);
}, 500);
});
}
在上述代码中,getUser1、getUser2、getUser3 都是异步函数,分别在 500 毫秒后分别正常返回了数字 1、2 和返回错误 3.而在 Promise.all 的 then 函数中,我们得到了一个包含 1、2 的数组,同时用户的错误也被 catch 到了。与 Promise.all 不同,Promise.allSettled 方法会等待所有 Promise 实例都返回对应的状态(不论是 resolved 还是 rejected),只有所有实例的状态都被转化为 settled 后,Promise.allSettled 才会执行。
例如,在下面这个例子中,getUser1、getUser2、getUser3 都返回了正确的值,但是在 getUser4 中出错了,Promise.allSettled 依然会异步等待所有的返回,最终返回状态集合。
Promise.allSettled([getUser1(), getUser2(), getUser3(), getUser4()])
.then(function(results) {
console.log(results);
});
function getUser1() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(1);
}, 500);
});
}
function getUser2() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(2);
}, 500);
});
}
function getUser3() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
reject(3);
}, 500);
});
}
function getUser4() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
reject(4);
}, 500);
});
}
在这个例子中,我们使用了 getUser4 函数,并在其中引发了错误。但是,Promise.allSettled 还是会异步等待结果并返回一个结果状态的集合。结果中每个对象都有一个 status 属性,该属性是 settled、fulfilled、rejected 中的一个。[
{ "status": "fulfilled", "value": 1 },
{ "status": "fulfilled", "value": 2 },
{ "status": "rejected", "reason": 3 },
{ "status": "rejected", "reason": 4 }
]
可以看到,每个 Promise 实例的状态都被等待到之后才执行,而且其中的 fulfilled 或者 reject 状态也以对象形式被统一返回了。var promise1 = Promise.resolve(3);
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
Promise.allSettled([promise1, promise2])
.then(function(results) {
console.log(results);
});
这个代码在前两个 Promise 实例中是已知的。可以看到,我们使用 Promise.resolve 和 Promise 构造函数来创建返回数字 3 和字符串 'foo' 的 Promise 实例,而结果数组始终都是相同的:[
{ "status": "fulfilled", "value": 3 },
{ "status": "fulfilled", "value": "foo" }
]
Promise.all([getUser1(), getUser2(), getUser3()])
.then(function(results) {
console.log(results);
})
.catch(function(err) {
console.log(err);
});
Promise.allSettled([getUser1(), getUser2(), getUser3()])
.then(function(results) {
console.log(results);
});
function getUser1() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(1);
}, 500);
});
}
function getUser2() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(2);
}, 500);
});
}
function getUser3() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
reject(new Error('error'));
}, 500);
});
}
这是包含 catch 函数的 Promise.all 和包含 then 函数的 Promise.allSettled 的输出结果:[
{ "status": "rejected", "reason": Error: error at ... },
undefined,
undefined
]
结果 2:[
{ "status": "fulfilled", "value": 1 },
{ "status": "fulfilled", "value": 2 },
{ "status": "rejected", "reason": Error: error at ... }
]
在这个例子中,我们使用了 getUser3 函数并引发了错误。但是,在使用 Promise.all 时,我们只会得到一个错误,而使用 Promise.allSettled 时我们会得到三种不同的状态值集合。