首页 文章

Calling Resolve函数转到JavaScript Promise中的Reject函数

提问于
浏览
1

我有以下代码:

return new Promise (function (resolve,reject) {
        if (this.ImageData && averageColor) {
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function () {
                if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
                    console.log("Image found");
                    resolve(xhr.response);
                }else {
                    console.log("Image not found");
                    reject();
                }
            }
            xhr.open('GET', 'http://localhost:8765/color/'+averageColor, true);
            xhr.send(null);
        }
        else {
            reject();
        }
    });

调用此代码的函数如下:

var v =  tile.getImage(tile.getColorAverage());
        v.then(function (value) {
            console.log("laughing");
        }).catch(function () {
           console.log("Catch called");
        });

问题在于我的承诺,我可以看到,如果条件正确并从服务器正确获取响应(因为console.log) . 然而,另一方面,它根本没有进入“当时”的承诺(甚至一次) . 出于某种原因,它会被拒绝 . 我疯了,因为我可以看到它执行了应该解决它的位但是我没有得到任何东西 . 任何帮助将非常感激 .

编辑:

现在我只跑了一次 . 这是我的console.log跟踪 . 现在更加困惑:

enter image description here

3 回答

  • 0
    xhr.onreadystatechange = function () {
        if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
            console.log(xhr.response);
            resolve(xhr.response);
        }else {
            reject();
        }
    }
    

    关于onreadystatechange的事情是,它被称为MULTIPLE次

    关于承诺解决的事情是,一旦被拒绝或解决,它就不能再被拒绝或重新获得

    第一次onreadystatechange被调用,状态将是1,而不是4 ...所以你拒绝

    你应该只在状态为4和(完成)和状态!= 200时拒绝

    xhr.onreadystatechange = function () {
        if (xhr.readyState == XMLHttpRequest.DONE) {
            if(xhr.status == 200) {
                console.log(xhr.response);
                resolve(xhr.response);
            } else {
                reject();
            }
        }
    }
    

    或者,使用onload / onerror - 尽管你仍然需要在onload中检查状态== 200

    xhr.onload= function () {
        if(xhr.status == 200) {
            console.log(xhr.response);
            resolve(xhr.response);
        } else {
            reject();
        }
    }
    
    
    xhr.onerror= function () {
        reject();
    }
    

    作为关于某些有效但看起来不对的东西的旁注

    return new Promise (function (resolve,reject) {
        if (this.ImageData && averageColor) {
    

    这里面的promise构造函数回调可能是窗口,甚至甚至可能在严格模式下未定义 - 你需要修复代码才能导致轨道问题

  • 4

    您遇到此问题的原因是 onreadystatechange 在请求完成之前被多次调用,在它完成之前,您将获得调用 rejectelse 条件 . 你应该只拒绝 DONExhr.status != 200 . 这是一个例子:

    if (xhr.readyState == XMLHttpRequest.DONE) {
        if (xhr.status == 200) {
            resolve(xhr.response);
        } else {
            reject();
        }
    }
    
  • 1

    Promise 构造函数中的 thiswindow ,除非专门设置为不同的值 . this.ImageData 将评估为 false 而不将 this 设置为 .ImageData 作为调用 new Promise() 时的属性的对象 .

    Promise 构造函数解析器函数中替换对 ImageData 属性为 ImageData 的对象的引用 .

    例如

    function resolver(resolve, reject) {
    
    }
    
    new Promise(resolver.bind(/*object that has `.ImageData` as property*/))
    

    此外,将 load 事件替换为 readystatechange 事件,并为 XMLHttpRequest object包含 error 事件处理程序 .

相关问题