承诺即使是真实的也正在拒绝

Promise is rejecting even tho it is true

如果 lunchTime 为真,则应记录午餐对象;如果为假,则应记录午餐对象。

控制台正在记录:错误:OOOOOPs
即使我尝试在 then 语句中记录 lunch 对象,它也只会记录错误消息

我的计划是手动将 lunchTime 的值切换为 false,这样我就可以测试 resolve/reject 承诺的一部分,但它是 运行 代码的 catch 部分,即使它应该解析。

const lunchTime = true;
    
    function orderMeSomeFood() {
        return new Promise((resolve, reject) => {
            if (lunchTime === true) {
                let lunch = {
                    food: "BBQ",
                    drink: "Zen WTR"
                };
    
                resolve(lunch);
            }
            else if (lunchTime === false) {
        const err = new Error('OOOOOPs')
        reject(err);
    }
            }
        })
    };
    
    orderMeSomeFood().then(() => {
        console.log(resolve);
    }).catch(() => {
        console.log(Error('OOOOOPs'));
    })

resolve 仅存在于承诺中,因此当您执行 console.log(resolve); 时会抛出错误,这就是您看到 OOOOOPs 消息的原因。

如果您想 console.log lunch 变量,您应该将代码更改为:

orderMeSomeFood().then(lunch => {
    console.log(lunch);
}).catch(() => {
    console.log(Error('OOOOOPs'));
})

const lunchTime = true;
    
    function orderMeSomeFood() {
        return new Promise((resolve, reject) => {
            if (lunchTime === true) {
                let lunch = {
                    food: "BBQ",
                    drink: "Zen WTR"
                };
    
                resolve(lunch);
            }
            else if (lunchTime === false) {
        const err = new Error('OOOOOPs')
        reject(err);
            }
        })
    };
    
    orderMeSomeFood().then(lunch => {
        console.log(lunch);
    }).catch(() => {
        console.log(new Error('OOOOOPs'));
    })

问题实际上出在这行代码上:

console.log(resolve);

也许你想成为:

console.log("resolved");

相反。实际的 resolve 变量和值仅存在于 new Promise() 执行函数内部,不存在于其他地方。所以,这会引发异常。

如果您没有意识到这一点,.then().catch() 处理程序中的异常将触发调用承诺链中的下一个 .catch() 处理程序。因此,当上述异常发生在 .then() 处理程序内部时,会导致代码执行跳转到下一个 .catch() 处理程序。


如果加上这个调试:

    orderMeSomeFood().then(() => {
        console.log("got to .then() handler");
        console.log(resolve);
    }).catch((e) => {
        console.log(e);
    });

然后,你会看到它到达了 .then() 处理程序,然后你会看到 catch 处理程序中的实际错误是 ReferenceError: resolve is not defined 并且行号将指向将 console.log(resolve) 作为违规陈述。


这里的一个教训是始终记录您在 .catch() 中遇到的实际异常,因为这通常是一个有用的提示,说明您的代码为何到达那里。


这是一个可运行的版本,其中包含更多日志记录,向您展示了实际流程:

const lunchTime = true;

function orderMeSomeFood() {
    return new Promise((resolve, reject) => {
        if (lunchTime === true) {
            let lunch = {
                food: "BBQ",
                drink: "Zen WTR"
            };
            console.log("about to resolve promise");
            resolve(lunch);
        } else if (lunchTime === false) {
            console.log("about to reject promise");
            reject(new Error('OOOOOPs'));
        }
    })
};

orderMeSomeFood().then(() => {
    console.log("got to .then() handler");
    console.log(resolve);
}).catch((e) => {
    console.log("got to .catch() handler");
    console.log(e.message, e.stack);
})

提供此输出:

about to resolve promise
got to .then() handler
got to .catch() handler
resolve is not defined ReferenceError: resolve is not defined
    at https://stacksnippets.net/js:32:17

因此,您可以看到以下内容:

  1. 它解决了承诺
  2. 它到达了 .then() 处理程序。
  3. console.log(resolve) 代码行的 .then() 处理程序中,它抛出了一个异常
  4. 将它发送到 .catch() 处理程序,现在它记录错误的原因