为什么.then()在JavaScript中没有承诺就可以工作?

时间:2019-02-14 18:51:18

标签: javascript promise

即使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);
    });
}

2 个答案:

答案 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)
    })
  })
  
      
  1. 返回一个值,然后返回的promise将返回的值作为其值进行解析;
  2.   

在代码中,这是Say 2,是您的原始问题。返回值时,then()返回一个Promise,该Promise将使用您返回的值进行解析。

  
      
  1. 不返回任何内容,然后返回的promise将使用未定义的值进行解析;
  2.   

与上述相同。

  
      
  1. 抛出错误,然后返回的承诺将被拒绝,并以抛出的错误作为其值;
  2.   

与上述相同,但现在then()返回一个Promise,但由于您的错误而被拒绝。

  
      
  1. 返回已经解决的承诺,然后以该承诺的值作为其值来解决之前返回的承诺;
  2.   

在代码中,这是Say 4,其中的诺言已经得到解决。因此,then()现在将返回一个Promise,该Promise将使用值4进行解析。

  
      
  1. 返回已经被拒绝的诺言,然后以该诺言的值作为其值来拒绝被返回的诺言;
  2.   

与上面相同,但现在拒绝了。

  
      
  1. 返回另一个未决的promise对象,届时返回的promise的解析/拒绝将在处理程序返回的promise的解析/拒绝之后。此外,届时返回的Promise值将与处理程序返回的Promise值相同。
  2.   

在代码中,这是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

的更多信息