Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript承诺/A+;链式循环typeError意味着无限循环溢出堆栈,还是意味着永远';待定';保证停止?_Javascript_Promise_Es6 Promise_Circular Reference - Fatal编程技术网

javascript承诺/A+;链式循环typeError意味着无限循环溢出堆栈,还是意味着永远';待定';保证停止?

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+所说的无限循环意味着什

这是我定制的承诺实现,请容忍我的粗略编码。问题是关于下面的检查,以确保承诺没有循环参考。承诺/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);
    }
}