为什么承诺 returns 也解决拒绝
Why Promise returns also Resolve on Reject
有人可以解释一下,为什么 Promise 在调用 reject 时会触发 then() 函数(以及 catch() 函数)?
调用 resolve 时,只有 then() 被触发 - OK
当调用 reject 时,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'));
调用 onFulfilled 或 onRejected 并带有承诺的实现值或拒绝原因(视情况而定),并且 return 一个新的承诺解析为被调用处理程序的 return 值。
注意这一行:
.then(console.log('logged in'))
then
方法需要 callback,但您正在调用函数并将 return
值作为参数传递。如果 console.log return 编辑了一个函数,该函数将由 then
在内部调用,以防 promise 得到解决。但事实并非如此,因为 console.log 没有 return 值! (它只是打印并退出)。
在 javascript 中,没有 return 值等于 undefined
。因此,您所做的是 在任何情况下都调用 console.log 并将未定义作为参数传递。因此,您的代码相当于:
console.log('logged in');
...
.then(undefined)
...
可能,您的意思是将日志记录回调作为参数传递,并让 Promise 在解析时调用该回调:
.then(() => console.log('logged in'));
或者,为了更清楚地了解正在发生的事情,您可以这样看:
function log() {
console.log('logged in');
}
...
.then(log);
我们不是调用函数,只是传递引用!
Promise 捕获后继续,尽管您试图将 promise 包装在 promise 中,因此您可以手动更改行为,这是一种反模式。链接承诺本身会更好,这样你就可以处理承诺链中的错误,然后继续执行(所以中间的捕获仍然可以跟随一个 then)。
不需要 .catch(error => reject('LogIn failed.'))
,因为如果您只是 return 来自 getSession()
的承诺,底部的 catch 语句将捕获错误。您正在尝试创建自己的 Promise,但是由于已经有一个 return 从 getSession()
编辑的 Promise,所以您真正想要做的是 return 直接从 return 中获得 Promise。
最后,您在底部写了一个 console.log
而没有将其包装在回调函数中,因此它会在调用 promise 时同步触发,而不是在 .then
触发时触发。
更简洁的解决方案是:
.....
// 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'));
有人可以解释一下,为什么 Promise 在调用 reject 时会触发 then() 函数(以及 catch() 函数)?
调用 resolve 时,只有 then() 被触发 - OK
当调用 reject 时,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'));
调用 onFulfilled 或 onRejected 并带有承诺的实现值或拒绝原因(视情况而定),并且 return 一个新的承诺解析为被调用处理程序的 return 值。
注意这一行:
.then(console.log('logged in'))
then
方法需要 callback,但您正在调用函数并将 return
值作为参数传递。如果 console.log return 编辑了一个函数,该函数将由 then
在内部调用,以防 promise 得到解决。但事实并非如此,因为 console.log 没有 return 值! (它只是打印并退出)。
在 javascript 中,没有 return 值等于 undefined
。因此,您所做的是 在任何情况下都调用 console.log 并将未定义作为参数传递。因此,您的代码相当于:
console.log('logged in');
...
.then(undefined)
...
可能,您的意思是将日志记录回调作为参数传递,并让 Promise 在解析时调用该回调:
.then(() => console.log('logged in'));
或者,为了更清楚地了解正在发生的事情,您可以这样看:
function log() {
console.log('logged in');
}
...
.then(log);
我们不是调用函数,只是传递引用!
Promise 捕获后继续,尽管您试图将 promise 包装在 promise 中,因此您可以手动更改行为,这是一种反模式。链接承诺本身会更好,这样你就可以处理承诺链中的错误,然后继续执行(所以中间的捕获仍然可以跟随一个 then)。
不需要 .catch(error => reject('LogIn failed.'))
,因为如果您只是 return 来自 getSession()
的承诺,底部的 catch 语句将捕获错误。您正在尝试创建自己的 Promise,但是由于已经有一个 return 从 getSession()
编辑的 Promise,所以您真正想要做的是 return 直接从 return 中获得 Promise。
最后,您在底部写了一个 console.log
而没有将其包装在回调函数中,因此它会在调用 promise 时同步触发,而不是在 .then
触发时触发。
更简洁的解决方案是:
.....
// 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'));