hawx1993/tech-blog

Promise 探索与实践

hawx1993 opened this issue · 0 comments

同步与异步的混用

在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));// 报错

对于Promisereject来说,如果抛出错误没有被捕获的话会报错,推荐总是使用.catch捕获错误,而不要使用.then的第二个参数来捕获,因为当使用promise.then(onFulfilled, onRejected) 的话
onFulfilled 中发生异常的话,在 onRejected 中是捕获不到这个异常的。

.then .catch 都会创建并返回一个 新的 promise对象。由于 .catch 方法是 .then 的别名,我们使用 .then 也能完成同样的工作。只不过使用 .catch 的话意图更明确,更容易理解。