javascript承诺/A+;链式循环typeError意味着无限循环溢出堆栈,还是意味着永远';待定';保证停止?
这是我定制的承诺实现,请容忍我的粗略编码。问题是关于下面的检查,以确保承诺没有循环参考。承诺/A+表示它将导致无限循环,但当我运行测试时,它将立即停止javascript承诺/A+;链式循环typeError意味着无限循环溢出堆栈,还是意味着永远';待定';保证停止?,javascript,promise,es6-promise,circular-reference,Javascript,Promise,Es6 Promise,Circular Reference,这是我定制的承诺实现,请容忍我的粗略编码。问题是关于下面的检查,以确保承诺没有循环参考。承诺/A+表示它将导致无限循环,但当我运行测试时,它将立即停止 if (bridgepromise === x) { return reject(new TypeError('Circular reference/Chaining cycle detected for promise #<Promise>')); } 它让我思考promises/A+所说的无限循环意味着什
if (bridgepromise === x) {
return reject(new TypeError('Circular reference/Chaining cycle detected for promise #<Promise>'));
}
它让我思考promises/A+所说的无限循环意味着什么,它是否意味着它会导致resolvePromise函数一次又一次地运行?还是说它永远不会解决或拒绝?
还是我的承诺还存在漏洞?还是我的测试不够?非常困惑
当I console.log在resolvePromise函数中时,它没有到达中的回调,也没有到达下的resolvePromise(bridgePromise,y,resolve,reject)
const PENDING=“PENDING”;
const completed=“completed”;
const REJECTED=“已拒绝”;
功能定制承诺(cb){
让self=这个
self.value=null;
self.error=null;
self.status=待定;
self.onFulfilledCallBack=[];
self.onRejectedCallBack=[];
函数解析(值){
//小心这是什么
设置超时(()=>{
如果(self.status==挂起){
//实际上,这里的设置状态是供以后使用的
自我状态=完成;
自我价值=价值;
self.onFulfilledCallBack.forEach(cb=>cb(value))}
})
}
函数拒绝(错误){
设置超时(()=>{
//实际上,这里的设置状态是供以后使用的
如果(self.status==挂起){
self.status=被拒绝;
self.error=错误;
self.onRejectedCallBack.forEach(cb=>cb(错误))}
})
}
cb(解决、拒绝)
}
//如果将then函数定义为箭头函数,请注意箭头函数的用法
//它将指向窗口
customizedPromise.prototype.then=函数(已完成,已拒绝){
让自我=这个;
让我们承诺;
oncompleted=typeof oncompleted==“函数”?oncompleted:value=>value;
onRejected=typeof onRejected==“函数”?onRejected:error=>{throw error};
如果(自我状态===已完成){
return bridgePromise=新的定制承诺((解析、拒绝)=>{
设置超时(()=>{
试一试{
设x=oncompleted(自我价值);
resolvePromise(bridgePromise,x,resolve,reject);
}捕获(e){
拒绝(e);
}
});
})
}
如果(self.status==拒绝){
return bridgePromise=新的定制承诺((解析、拒绝)=>{
设置超时(()=>{
试一试{
设x=onRejected(self.error);
resolvePromise(bridgePromise,x,resolve,reject);
}捕获(e){
拒绝(e);
}
});
});
}
如果(self.status==挂起){
return bridgePromise=新的定制承诺((解析、拒绝)=>{
self.onFulfilledCallBack.push((值)=>{
试一试{
设x=oncompleted(值);
resolvePromise(bridgePromise,x,resolve,reject);
}捕获(e){
拒绝(e);
}
});
self.onRejectedCallBack.push((错误)=>{
试一试{
设x=onRejected(错误);
resolvePromise(bridgePromise,x,resolve,reject);
}捕获(e){
拒绝(e);
}
});
});
}
}
函数resolvePromise(bridgePromise,x,resolve,reject){
let called=假;
/*当我运行测试时,如果条件不在这里,则为*/
**如果(bridgePromise==x){
返回拒绝(新类型错误('检测到承诺的循环引用/链接循环#');
}**
如果(x!=null&((typeof x=='object')| |(typeof x=='function')){
试一试{
设then=x.then;
if(typeof then==“函数”){
然后,调用(x,y=>{
log(“它没有到达这里,因此没有引用循环”)
如果(被调用)返回;
调用=真;
resolvePromise(bridgePromise,y,resolve,reject);
},错误=>{
如果(被调用)返回;
调用=真;
拒绝(错误);
})
}否则{
决议(x);
}
}捕获(e){
如果(被调用)返回;
调用=真;
拒绝(e);
}
}
否则{
决议(x);
}
}
让testPromise=p。那么(value=>{return testPromise})
为什么要返回刚刚在同一句话中声明的内容?那么这个有什么意义呢@Ngoc I试图复制导致连锁循环的案例。如果一个承诺是由一个参与循环的thenable链的thenable解析的,因此[[Resolve]](承诺,thenable)的递归性质最终导致再次调用[[Resolve]](承诺,thenable),遵循上述算法将导致无限递归。我们鼓励但不要求实现检测此类递归并拒绝承诺,原因是信息类型错误。如果它从未到达中的回调,则,则此承诺的实现中肯定存在错误。我已经盯着它看了15分钟了,但它并不是真的冲着我跳。也许你需要一些简单的测试用例来找出你的bug在哪里?这是我的地址
let p = new customizedPromise((resolve, reject) => {
resolve(1)
})
let testPromise = p.then(value => { return testPromise })
testPromise.then(data => console.log(data))
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
function customizedPromise(cb) {
let self = this
self.value = null;
self.error = null;
self.status = PENDING;
self.onFulfilledCallBack = [];
self.onRejectedCallBack = [];
function resolve(value) {
// be careful about setTimeout's this
setTimeout(() => {
if (self.status === PENDING){
//actually here setting status is for later use
self.status = FULFILLED;
self.value = value;
self.onFulfilledCallBack.forEach(cb => cb(value))}
})
}
function reject(error) {
setTimeout(() => {
//actually here setting status is for later use
if (self.status === PENDING){
self.status = REJECTED;
self.error = error;
self.onRejectedCallBack.forEach(cb => cb(error))}
})
}
cb(resolve, reject)
}
// be careful about arrow function's this if you define then function as an arrow function
// it will point to the window
customizedPromise.prototype.then = function (onFulfilled, onRejected) {
let self = this;
let bridgePromise;
onFulfilled = typeof onFulfilled === "function" ? onFulfilled : value => value;
onRejected = typeof onRejected === "function" ? onRejected : error => { throw error };
if (self.status === FULFILLED) {
return bridgePromise = new customizedPromise((resolve, reject) => {
setTimeout(() => {
try {
let x = onFulfilled(self.value);
resolvePromise(bridgePromise, x, resolve, reject);
} catch (e) {
reject(e);
}
});
})
}
if (self.status === REJECTED) {
return bridgePromise = new customizedPromise((resolve, reject) => {
setTimeout(() => {
try {
let x = onRejected(self.error);
resolvePromise(bridgePromise, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
if (self.status === PENDING) {
return bridgePromise = new customizedPromise((resolve, reject) => {
self.onFulfilledCallBack.push((value) => {
try {
let x = onFulfilled(value);
resolvePromise(bridgePromise, x, resolve, reject);
} catch (e) {
reject(e);
}
});
self.onRejectedCallBack.push((error) => {
try {
let x = onRejected(error);
resolvePromise(bridgePromise, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
}
function resolvePromise(bridgePromise, x, resolve, reject) {
let called = false;
/* this if condition is not here when I run test */
**if (bridgePromise === x) {
return reject(new TypeError('Circular reference/Chaining cycle detected for promise #<Promise>'));
}**
if (x != null && ((typeof x === 'object') || (typeof x === 'function'))) {
try {
let then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
console.log("it is not reaching here, hence no reference cycle")
if (called) return;
called = true;
resolvePromise(bridgePromise, y, resolve, reject);
}, error => {
if (called) return;
called = true;
reject(error);
})
} else {
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
}
else {
resolve(x);
}
}