简体   繁体   English

为何Promise退货也要解决

[英]Why Promise returns also Resolve on Reject

can someone explain, why Promise fires then() function (and also catch() function) when reject is called? 有人可以解释,为什么拒绝调用时Promise触发then()函数(以及catch()函数)?

When resolve is called, only then() is trigger - OK 调用resolve时,仅then()被触发-确定

When reject is called, both then() and catch() function are called - Problem 当拒绝被调用时,那么then()和catch()函数都被调用-问题

static logIn(email, password) {

    async function getSession () {

        let data = new FormData();
        data.append('email', email);
        data.append('password', password);

        const response = await fetch(
            url,
            {
                method: 'POST',
                mode:   'cors',
                body:   data,
                cache:  'no-cache',
                headers: {
                    'Accept': 'application/json',
                },
            }
        );

        const json = await response.json();

        return json;
    }

    return new Promise((resolve, reject) => {
        getSession()
            .then(json => {
                if (json.status === 'ok') {
                    resolve('OK');
                } else {
                    reject('LogIn failed.');
                }
            })
            .catch(error => reject('LogIn failed.'))

    });

};

logIn()
    .then(console.log('logged in'))
    .catch(error => console.log('not logged in'));

Notice this line: 注意这一行:

.then(console.log('logged in'))

then method expects a callback , but you're invoking a function and passing the return value as parameter. then方法需要一个回调 ,但是您正在调用一个函数并将return值作为参数传递。 If console.log returned a function, that function would be invoked internally by then in case the promise was resolved. 如果console.log返回了一个函数, then在该承诺被解决的情况下,该函数将在内部被调用。 But this is not the case, since console.log hasn't a return value! 但是事实并非如此,因为console.log没有返回值! (It just prints and exit). (它只是打印并退出)。

In javascript, no return value is equal to undefined . 在javascript中,没有返回值等于undefined So, what you are doing is invoking console.log in any case and passing undefined as parameter. 因此,无论如何,您要做的是调用console.log并传递undefined作为参数。 You code is thus equivalent to: 因此,您的代码等效于:

console.log('logged in');
...
  .then(undefined)
  ...

Probably, what you meant is to pass a logging callback as parameter, and let the Promise invoke that callback when it is resolved: 可能是要传递日志回调作为参数,然后让Promise在解决该回调时调用该回调:

.then(() => console.log('logged in'));

Or, to be more clean about what's happening, you can see it in this way: 或者,为了更清楚地了解正在发生的事情,您可以通过以下方式查看它:

function log() {
  console.log('logged in');
}

...
  .then(log);

We are not invoking the function, just passing the reference! 我们不调用函数,只是传递引用!

Promises continue after a catch , although you're trying to wrap a promise in a promise, so you can manually change the behaviour, that is an anti-pattern. 承诺在捕获后仍会继续 ,尽管您正在尝试将诺言包装在诺言中,所以您可以手动更改行为,这是一种反模式。 Chaining the promise itself would be better, so you are able to handle errors in the promise chain, and then continue execution (so a catch in the middle can still be followed by a then). 将promise链接起来会更好,因此您可以处理promise链中的错误,然后继续执行(因此中间仍然可以接一个then)。

There is no need for .catch(error => reject('LogIn failed.')) because your catch statement at the bottom will catch the error if you just return the promise from getSession() . 不需要.catch(error => reject('LogIn failed.'))因为如果您只是从getSession()返回promise,则底部的catch语句将捕获错误。 You are trying to create your own Promise, but as there is already a promise being returned from getSession() so what you really want to do is return the promise from that directly. 您正在尝试创建自己的Promise,但是由于已经从getSession()返回了一个Promise,所以您真正想要做的就是直接从中返回Promise。

Finally, you are writing a console.log at the bottom without wrapping it in a callback function, so it is firing synchronously, when the promise is invoked, not when .then is firing. 最后,您在底部编写了console.log而不将其包装在回调函数中,因此在调用promise .then不是.then触发时.then它正在同步触发。

A neater solution is: 更整洁的解决方案是:

.... ....

    // return the promise from getSession, why wrap it in another?
    return getSession()
        .then(json => {
            if (json.status === 'ok') {
                return 'OK';
            } else {
                // Throwing an error in a then callback will trigger the catch block below
                throw new Error('LogIn failed.');
            }
        });
}

logIn()
    .then(() => console.log('logged in'))
    .catch(error => console.log('not logged in'));

使用承诺的实现值或拒绝原因(视情况而定)调用onFulfilled或onRejected,并返回解析为被调用处理程序返回值的新承诺。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM