即使notPromise()只是一个常规函数,为什么调用第二个函数.then(notPromise)仍将参数传递给第三个函数.then(promiseC)?
我认为.then()仅可以使用promises,但是以某种方式它仍然可以正确执行(并传递参数)。
promiseA()
.then(notPromise)
.then(promiseC);
function promiseA() {
return new Promise(function (resolve, reject) {
const string = "a";
resolve(string);
});
}
function notPromise(string) {
const nextString = "b"
const finalString = string + nextString;
return finalString;
}
function promiseC(string) {
return new Promise(function (resolve, reject) {
const nextString = "c";
const finalString = string + nextString;
alert(finalString);
resolve(finalString);
});
}
答案 0 :(得分:6)
then()方法返回一个Promise。 See docs。
promise具有处理程序方法。一旦实现或拒绝了Promise,相应的处理函数将被异步调用。处理函数的行为遵循一组特定的规则as stated here。
让我们一个接一个地讨论它们。这是我们将并排检查的代码。没什么特别的,只是一堆许诺返回价值。
let sequence = new Promise(function (resolve) {
console.log('Say 1')
resolve(1)
})
sequence
.then(() => {
console.log('Say 2')
return 2
})
.then(() => {
console.log('Say 3')
})
.then(() => {
console.log('Say 4')
return Promise.resolve(4)
})
.then(() => {
return new Promise(function (resolve) {
console.log('Say 5')
setTimeout(() => { resolve(5) }, 1000)
})
})
- 返回一个值,然后返回的promise将返回的值作为其值进行解析;
在代码中,这是Say 2
,是您的原始问题。返回值时,then()
返回一个Promise,该Promise将使用您返回的值进行解析。
- 不返回任何内容,然后返回的promise将使用未定义的值进行解析;
与上述相同。
- 抛出错误,然后返回的承诺将被拒绝,并以抛出的错误作为其值;
与上述相同,但现在then()
返回一个Promise,但由于您的错误而被拒绝。
- 返回已经解决的承诺,然后以该承诺的值作为其值来解决之前返回的承诺;
在代码中,这是Say 4
,其中的诺言已经得到解决。因此,then()
现在将返回一个Promise,该Promise将使用值4进行解析。
- 返回已经被拒绝的诺言,然后以该诺言的值作为其值来拒绝被返回的诺言;
与上面相同,但现在拒绝了。
- 返回另一个未决的promise对象,届时返回的promise的解析/拒绝将在处理程序返回的promise的解析/拒绝之后。此外,届时返回的Promise值将与处理程序返回的Promise值相同。
在代码中,这是Say 5
。如果您返回的承诺尚未解决,then()
将返回带有承诺结果的Promise,即5。
要注意的一件事是,我最近也实际上了解到(由@Bergi在评论中建议):then()
方法始终在链回调甚至开始执行之前构造并返回一个新的Promise。传递给then()
的回调仅告诉诺言应使用诺言解析/拒绝的值/错误。
总而言之,这就是then()
链接即使在您没有专门返回新Promise的情况下仍然有效的原因-因为then()
方法总是在幕后构造一个新的Promise并拒绝/解析该Promise。您返回的值。在上述情况下,最复杂的情况是在回调中返回Promise时,在这种情况下,您的回调诺言的结果将传递到then()
诺言。
答案 1 :(得分:0)
这与诺言链有关,如果随后对then()
的调用不是诺言也没关系,它们都是诺言链的一部分,好处是您可以继续链接诺言,这允许您连续执行几个异步/承诺操作(如您的示例所述),这是一个真实的示例:
// This is the generic http call
private callServer(url: string, method: string, body?: any) {
const uri = env.apiUrl + url;
const session = this.sessionToken;
const headers = {
'Content-Type': 'application/json',
'credentials': 'same-origin',
'x-auth-token': session,
};
return fetch(uri, {
method,
headers,
body: JSON.stringify(body),
})
.then(this.wait) // this is a timer, returns a promise
.then(this.checkStatus) // this is a sync call
.then((r) => r.text()) // r.text() is async
.then((tx) => tx ? JSON.parse(tx) : {}); // this is sync
}
您可以了解有关承诺链here
的更多信息