promise的then办法会返回一个promise对象。如果用户在写代码的过程中,将本身给返回进来,就会报类型谬误。
测试代码:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Promise.then办法返回本身测试</title></head><body> <script> var p = new Promise(function (resolve, reject) { resolve(100); }) var p1 = p.then(function (value) { console.log(value) return p1; }) p1.then(function () {}, function (resson) { console.log(resson.message) }) </script></body></html>
在控制台中打印如下,提醒循环调用。
100Chaining cycle detected for promise #<Promise>
因而须要在之前的代码中做一下必要的判断。如果返回的是本身,就要报类型谬误。resolvePromise
办法中加一个参数,将then办法中返回promise对象传入
function resolvePromise(promise2, e, resolve, reject) { if (promise2 === e) { return reject(new TypeError("Chaining cycle detected for promise #<Promise>")) } if (e instanceof MyPromise) { // promise对象 // e.then((value) => { // resolve(value) // }, (reason) => { // reject(reason) // }) // 简化代码 e.then(resolve, reject); } else { //一般值 resolve(e); }}
然而这个代码是有问题的,resolvePromise
办法存在于then办法中promise的执行器外面。而他的第一个参数却是promise对象的返回值,resolvePromise
无奈获取到这个返回值,这显然有问题。
解决办法就是将then办法中判断状态之后的逻辑代码编程异步代码,让所有的同步先执行,promise返回值就存在了。此时resolvePromise
就能获取到new Promise
的返回值。
if (this.status === FULFILLED) { setTimeout(() => { // 定义胜利回调返回值,传给下一个then的胜利回调 let successRtn = successCallback(this.value); // 判断 x 的值是一般值还是promise对象 // 如果是一般值 间接调用resolve // 如果是promise对象 查看promsie对象返回的后果 // 再依据promise对象返回的后果 决定调用resolve 还是调用reject // 执行resolve办法,相当于把返回值传递给下一个then的胜利回调函数 resolvePromise(promise2, successRtn, resolve, reject); }, 0); }
测试代码批改一下
let promise = new MyPromise((resolve, reject) => { resolve('---success----');})let p1 = promise.then(value => { console.log(value); return p1;}, reason => { console.log(reason)})p1.then(value => { console.log(value)},reason=>{ console.log(reason)})
控制台打印
---success----TypeError: Chaining cycle detected for promise #<Promise>
测试胜利。