为什么.then()在JavaScript中没有promise?

ufj5ltwl  于 2023-03-28  发布在  Java
关注(0)|答案(3)|浏览(162)

为什么调用第二个函数.then(notPromise)仍然将参数传递给第三个函数.then(promiseC),即使notPromise()只是一个普通函数?
我以为只有promise才能和.then()一起使用,但不知何故,它仍然可以正确地执行(并传递参数)。

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);
    });
}
qojgxg4l

qojgxg4l1#

then()方法返回Promise. See docs
一个Promise有一个handler方法。一旦一个Promise被实现或拒绝,相应的handler函数将被异步调用。handler函数的行为遵循一组特定的规则,如下所述。
让我们一个接一个地看,下面是我们将一起检查的代码,它没什么特别的,只是一串返回值的promise。

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将以返回的值作为其值进行解析;
在代码中,这是Say 2,也就是你最初的问题。当返回一个值时,then()返回一个Promise,这个Promise用你返回的值来解决。
1.不返回任何内容,则then返回的promise将使用未定义的值进行解析;
与上述相同。
1.抛出错误,则返回的promise将以抛出的错误作为其值被拒绝;
和上面一样,除了现在then()返回一个Promise,它被你的错误拒绝。
1.返回一个已经解析的承诺,则返回的承诺将以该承诺的值作为其值进行解析;
在代码中,这是Say 4,其中promise已经被解析。所以现在then()返回一个Promise,它被解析为值4。
1.返回一个已经被拒绝的promise,则返回的promise会被拒绝,并以该promise的值作为其值;
和上面一样,只是现在拒绝了。
1.返回另一个挂起的promise对象,则此时返回的promise的解析/拒绝将在处理程序返回的promise的解析/拒绝之后。而且,此时返回的promise的值将与处理程序返回的promise的值相同。
在代码中,这是Say 5。如果您返回一个尚未解决的promise,then()将返回一个Promise,其中包含您的promise的结果,即5。
需要注意的一点是,我最近实际上也学到了(@Bergi在评论中建议),then()方法总是在链回调开始执行之前构造并返回一个新的Promise。您传递给then()的回调只是告诉Promise应该解决/拒绝的值/错误。
总而言之,这就是为什么then()链接即使在你没有明确返回一个新Promise的情况下也能工作的原因--因为then()方法总是在幕后构造一个新的Promise,并使用你返回的值拒绝/解析那个Promise。上述场景中最复杂的情况是当你在回调中返回一个Promise时,在这种情况下,回调promise的结果会传递给then() promise。

laawzig2

laawzig22#

它与promise链有关,如果对then()的后续调用不是promise也没关系,它们都是promise链的一部分,好处是你可以继续链接promise,这允许你连续执行几个async/promise操作(如你的示例所述),下面是一个真实世界的示例:

// 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
  }

你可以阅读更多关于promise chain here的内容

uqdfh47h

uqdfh47h3#

TL;DR

then()总是 * 同步地 * 返回一个promise px(允许链接),但如果它的第一个参数是一个不返回promise的函数fx(),JS运行时将解析(fulfill)px只要链中的前一个promise被解决(fulfilled),并将fx()的返回值视为下一个then()的第一个参数的(function)参数。
例如,函数:

function startAsyncStuff1() {
    console.log("startAsyncStuff1 - enter")
    fetch("http://date.jsontest.com")
        .then((response) => response.json())
        .then((data) => console.log("startAsyncStuff1 - result:", data))
}

其中第一个then()的参数返回一个promise,记录:

startAsyncStuff1 - enter 
startAsyncStuff1 - result: Object { date: "03-26-2023", milliseconds_since_epoch: 1679845802541, time: "03:50:02 PM" }

而函数:

function startAsyncStuff2() {
    console.log("startAsyncStuff2 - enter")
    fetch("http://date.jsontest.com")
        .then((response) => response.json())
        .then(() => "log this data instead of the json")
        .then((data) => console.log("startAsyncStuff2 - result:", data))
}

其中第二个then()的参数返回一个字符串,记录:

startAsyncStuff2 - enter
startAsyncStuff2 - result: log this data instead of the json

因为返回的字符串覆盖了response.json()在实现时返回的promise所传递的data

相关问题