共计 1713 个字符,预计需要花费 5 分钟才能阅读完成。
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>
在控制台中打印如下,提醒循环调用。
100
Chaining 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>
测试胜利。
正文完
发表至: javascript
2021-08-13