【问题标题】:Console log from earlier promise appears after console log from latest promise [duplicate]来自早期承诺的控制台日志出现在来自最新承诺的控制台日志之后[重复]
【发布时间】:2023-03-23 06:41:01
【问题描述】:

以下不是我的确切代码,但我只是想概述一下结构。当我运行代码时,我得到控制台日志的顺序是这样的:

  1. '完成'
  2. json

我希望这是相反的情况,因为为了让函数 2 完成(并发送“完成”解析值),函数 3 必须先完成。

我想了解为什么它不能那样工作。

function1().then(() => {
      return function2()
    ).then((message) => {
      console.log(message)
    })

    function function2() {
      return new Promise((resolve, reject) => {
        fetch(url, {
            method: 'get',
            body: null,
            headers: {
              "Content-Type": "application/json; charset=UTF-8",
              "Accept": "application/json; charset=UTF-8",

            },
          })
          .then(res => res.json())
          .then((json) => {
            return function3(json)
          })

        resolve('Done')
      })
    }

    function function3(json) {
      console.log(json)
    }

【问题讨论】:

标签: javascript promise sequence console.log


【解决方案1】:

您甚至在您的fetch 完成之前就调用了resolve

如果你把它移到另一个 then 中就可以了:

// ...
.then(res => res.json())
.then((json) => {
    return function3(json)
})
.then(() => {
    resolve('Done')
})

但事实上,整个new Promise 甚至都没有必要,因为fetch 已经返回了一个承诺!

// ...

function function2() {
    return fetch(url, { // It's important to actually *return* the promise here!
        method: 'get',
        body: null,
        headers: {
            "Content-Type": "application/json; charset=UTF-8",
            "Accept": "application/json; charset=UTF-8"
        }
    })
    .then(res => res.json())
    .then((json) => {
        return function3(json)
    })
    .then(() => {
        return 'Done'
    })
}

这可以使用async/await进一步简化:

// I moved this into a function because the global module-level code
// is not in an async context and hence can't use `await`.
async function main () {
  await function1()
  console.log(await function2())
}

async function function1 () {
  // I don't know what this does, you didn't include it in your code snippet
}

async function function2 () {
  const response = await fetch(url, {
    method: 'get',
    body: null,
    headers: {
      "Accept": "application/json; charset=UTF-8"
    }
  })
  
  const json = await response.json()
  await function3(json)

  return 'Done'
}

// At the moment this wouldn't have to be async because you don't do anything
// asynchronous inside, but you had `return function3(json)` in the original code,
// so I assume it is *going* to be async later.
async function function3 (json) {
  console.log(json)
}

// Don't forget to .catch any rejections here! Unhandled rejections are a pain!
main().catch(console.error)

(当我这样做时,我删除了 Content-Type 标头,因为它对 GET 请求毫无意义。)

【讨论】:

  • 我还没有尝试使用 async / await 你的简化版本,但你对“then”承诺的解释是正确的。
  • 只是补充一下,我现在已经尝试了 async / await 示例,它成功了。这东西终于有意义了——太棒了:)
【解决方案2】:

在函数 2 中,调用了 fetch,并且只有 .then() 链被暂停。下一个要读取的 javascript 是 resolve() ,它解决了 Promise。几秒钟后,promise 解析并继续沿链向下运行到函数 3,其中记录了“完成”

【讨论】:

    【解决方案3】:

    您错过了这样一个事实,即 fetch 异步工作并被加载到回调队列,而这里的 resolve 以同步方式工作。因此,即使 fetch 在 resolve 之前完成,由于 javascript 循环,它仍然会在 resolve 之后执行。您需要在更远的 fetch 链中进行链式解析以实现所需的功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多