Promise关键问题



1.修改promise的状态

 let p = new Promise((resolve, reject) => {
            //1. resolve 函数
            // resolve('ok'); // pending   => fulfilled (resolved)
            //2. reject 函数
            // reject("error");// pending  =>  rejected 
            //3. 抛出错误
            // throw '出问题了',rejected;
        });

通过throw也可以修改promise状态

image-20210806001915338

2.能否执行多个回调

let p = new Promise((resolve, reject) => {
   resolve('OK');
});

///指定回调 - 1
p.then(value => {
   console.log(value);
});

//指定回调 - 2
p.then(value => {
   alert(value);
});//都可以执行

3.改变状态与指定回调的顺序

1. 如果先指定的回调, 那当状态发生改变时, 回调函数就会调用, 得到数据

// 常规: 先指定回调函数, 后改变的状态
new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1) // 后改变的状态(同时指定数据), 异步执行回调函数
  }, 1000);
}).then(// 先指定回调函数, 保存当前指定的回调函数
  value => {},
  reason => {console.log('reason', reason)}
)

2. 如果先改变的状态, 那当指定回调时, 回调函数就会调用, 得到数据

// 如果先改状态, 后指定回调函数
new Promise((resolve, reject) => {
  resolve(1) // 先改变的状态(同时指定数据)
}).then(// 后指定回调函数, 同步执行回调函数
  value => {console.log('value2', value)},
  reason => {console.log('reason2', reason)}
)

总结:只有当状态改变才会执行回调

4.then方法返回promise结果由什么决定

let p = new Promise((resolve, reject) => {
    resolve('ok');
});
//执行 then 方法
let result = p.then(value => {
    // console.log(value);
    //1. 抛出错误
    // throw '出了问题';
    //2. 返回结果是非 Promise 类型的对象
    // return 521;
    //3. 返回结果是 Promise 对象
    // return new Promise((resolve, reject) => {
    //     // resolve('success');
    //     reject('error');
    // });
    //不返回,promise的值是undefined
    //返回的是pending状态的promise,会中断链式调用
}, reason => {
    console.warn(reason);
});
console.log(result);

1.抛出错误,then返回的promise对象是rejected

2.promise内部返回结果是非promise对象,return number/string/boolean,then的返回的promise对象是resolve

3.then的promise返回结果是promise对象,由内部返回的promise对象来绝对then的promise对象的状态

4.then内部不返回值,后面的then调用默认是undefined

5.promise如何串联多个任务

1.promise的then返回一个promise对象,通过链式调用即可

2.通过then串联同步/异步操作

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('OK');
    }, 1000);
});

p.then(value => {
    return new Promise((resolve, reject) => {
        resolve("success");
    });
}).then(value => {
    console.log(value);
}).then(value => {
    console.log(value);
})

6.异常的穿透

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('OK');
        // reject('Err');
    }, 1000);
});

p.then(value => {
    // console.log(111);
    throw '失败啦!';
}).then(value => {
    console.log(222);
}).then(value => {
    console.log(333);
}).catch(reason => {
    console.warn(reason);
});

异常的穿透,在改变状态之后执行then中的回调,then的返回结果是promise,但是改变了promise的状态,是rejected,返回的rejected的promise对象直接穿透到catch中

7.如何中断promise链

有且只有一个方式返回一个pending状态的promise

return new Promise(() => {})

let p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('OK');
    }, 1000);
});

p.then(value => {
    console.log(111);
    //有且只有一个方式
    return new Promise(() => {});
}).then(value => {
    console.log(222);
}).then(value => {
    console.log(333);
}).catch(reason => {
    console.warn(reason);
});

8.错误的捕获

首页我们先要区分几个概念:
第一,reject是用来抛出异常的,catch是用来处理异常的;
第二:reject是Promise的方法,而then和catch是Promise实例的方法(Promise.prototype.then 和 Promise.prototype.catch)。

1. 区别

主要区别就是,如果在then的第一个函数里抛出了异常,后面的catch能捕获到,而then的第二个函数捕获不到。

catch只是一个语法糖而己 还是通过then 来处理的,大概如下所示字体:

Promise.prototype.catch = function(fn){
    return this.then(null,fn);
}

then的第二个参数和catch捕获错误信息的时候会就近原则,如果是promise内部报错,reject抛出错误后,then的第二个参数和catch方法都存在的情况下,只有then的第二个参数能捕获到,如果then的第二个参数不存在,则catch方法会捕获到。

const promise = new Promise((resolve, rejected) => {
    throw new Error('test');
});

//此时只有then的第二个参数可以捕获到错误信息
promise.then(res => {
    //
}, err => {
    console.log(err);
}).catch(err1 => {
    console.log(err1);
});


//此时catch方法可以捕获到错误信息
promise.then(res => {
    //
}).catch(err1 => {
    console.log(err1);
});


//此时只有then的第二个参数可以捕获到Promise内部抛出的错误信息
promise.then(res => {
    throw new Error('hello');
}, err => {
    console.log(err);
}).catch(err1 => {
    console.log(err1);
});

//此时只有then的第二个参数可以捕获到Promise内部抛出的错误信息
promise.then(res => {
    throw new Error('hello');
}, err => {
    console.log(err);
});


//此时catch可以捕获到Promise内部抛出的错误信息
promise.then(res => {
    throw new Error('hello');
}).catch(err1 => {
    console.log(err1);
});

2. 两个捕获方法的比较

// bad
promise
  .then(function(data) {
    // success
  }, function(err) {
    // error
  });

// good
promise
  .then(function(data) { //cb
    // success
  })
  .catch(function(err) {
    // error
  });

上面代码中,第二种写法要好于第一种写法,理由是第二种写法可以捕获前面then方法执行中的错误,也更接近同步的写法(try/catch)。因此,建议总是使用catch方法,而不使用then方法的第二个参数。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM