Promise 探索与实践
hawx1993 opened this issue · 0 comments
hawx1993 commented
同步与异步的混用
在Promise中,同步和异步同时调用可能会造成混乱,执行顺序如下所示:
let promise = new Promise(function (resolve,reject){
console.log("inner promise"); // 1
// resolve('resolve');//resolve将运行得到的结果传出来,而then接受该参数给回调继续执行后面的
reject('reject')
});
promise.then(function(value){
console.log(value);
},function (err) {
console.log(err);//3; Promise对象的状态resolved失败变为Reject状态时调用(可选)
});
console.log("outer promise"); // 2
Promise对象还是同步执行的,.then
才是异步执行,所以先输出inner promise
对异步回调函数进行同步调用,还可能导致栈溢出或者异常处理错乱等问题。如果想在将来的某个时刻调用异步回调,可以使用setTimeout等异步API。
resolve和reject
var name,
p = new Promise(function (resolve,reject) {
setTimeout(function () {
// resolve();如果这里是resolve,那么下面会依次输出trigkit4和mike
reject();
},1000)
});
p.then(function () {
name = 'trigkit4';
console.log(name);
}).then(function () {
name = 'mike';
console.log(name)
},function (err) {
console.log('reject')
});
//推荐的写法
p.then(function(data) { //cb
})
.catch(function(err) {
console.log('err')
});
当使用 then(resolveHandler, rejectHandler)
,rejectHandler
不会捕获在 resolveHandler
中抛出的错误。
somePromise().then(function () {
throw new Error('oh noes');
}).catch(function (err) {
// I caught your error! :)
});
somePromise().then(function () {
throw new Error('oh noes');
}, function (err) {
// I didn't catch your error! :(
});
var p = Promise.resolve();//Promise.resolve()
将现有对象转为Promise对象
Promise.resolve(Object)
转为Promise对象
let promise = {
then: function (resolve, reject) {
resolve('hello');
reject(new Error('error'));//resolved再抛出错误无效,不执行
}
};
let p = Promise.resolve(promise);
p.then(v => console.log(v));//hello
reject Error
var pro = {
then: function (resolve, reject) {
reject(new Error('error'));//resolved再抛出错误无效,不执行
}
};
var promiseObj = Promise.resolve(pro);
promiseObj.then(v => console.log(v));// 报错
对于Promise
的reject
来说,如果抛出错误没有被捕获的话会报错,推荐总是使用.catch
捕获错误,而不要使用.then
的第二个参数来捕获,因为当使用promise.then(onFulfilled, onRejected)
的话
在 onFulfilled
中发生异常的话,在 onRejected
中是捕获不到这个异常的。
.then
和 .catch
都会创建并返回一个 新的 promise
对象。由于 .catch
方法是 .then
的别名,我们使用 .then
也能完成同样的工作。只不过使用 .catch
的话意图更明确,更容易理解。