【问题标题】:Wait until nested promises resolve等到嵌套的 Promise 解决
【发布时间】:2019-01-02 21:08:33
【问题描述】:

我正在尝试对数据库进行一系列嵌套调用,并希望在结果全部返回后做一些事情。我是新手,如果我完全做错了,请原谅我(可能是这种情况)

我的代码目前是这样的:

getVideos(user).then((videos) => {
  videos.forEach((video) => {
    getImage(video).then(() => {
      getMembers().then((members) => {
        getComments().then((comments) => {
          getKeywords().then((keywords) => {
            getTranscript().then((transcript) => {
              console.log(members, comments, keywords, transcript)
            }
          }
        }
      }
    })
  })
})

这显然是超级低效的,因为getMembers()getComments()getKeywords()getTranscript()不需要互相等待,都可以异步调用。此外,getImage() 可以为循环中的每个视频异步调用,而无需等待。

我正在尝试更改代码以将这些承诺捆绑成一个大承诺,以便一旦解决,我就可以在一个地方访问所有获取的数据。这是我的尝试,但它会打印出来

承诺{...}、承诺{...}、承诺{...}、承诺{...}

而不是获取的数据。

知道我做错了什么以及如何正确地将所有这些嵌套的 Promise 合并为一个吗?谢谢

let members, comments, keywords, transcript

getVideos(user).then((videos) => {
   let promises = []
   videos.forEach((video) => {
      let p = getImage(video).then(() => {
        members = getMembers()
        comments = getComments()
        keywords = getKeywords()
        transcript = getTranscript()
        return Promise.all([members, comments, keywords, transcript])
      })
      promises.push(p)
  })
  return Promise.all(promises)
})
.then(() => {
  console.log(members, comments, keywords, transcript)
})

【问题讨论】:

  • 如果你改为console.log(arguments); 会怎样?
  • 您需要使用嵌入的 Promise (members, comments...) 解析的数据设置全局状态,并根据该状态打印或将输出例程移动到 @987654332 @handlers 表示承诺。
  • 最终解决方案肯定取决于您的需求,但我建议您查看Promise.all。它允许您在继续执行之前等待多个承诺。因此,如果您想同时检索有关特定视频的所有信息,您可以。如果您想等待所有视频信息返回,您可以这样做。
  • 不清楚这里取决于什么。 getMembers()getComments()getTranscript() 等不要带任何参数。那么他们总是返回同样的东西吗?在打电话给他们之前,他们是否依赖于发生的任何事情?他们在读取全局变量吗?
  • 如果你想序列化你的请求,那么链接你的承诺。返回内在的承诺。搜索“承诺链”以获取更多信息。但是,您可能不需要序列化它们。您可以发出所有请求并使用Promise.all() 知道它们何时完成。

标签: javascript asynchronous promise es6-promise


【解决方案1】:

尝试使用两个 Promise.alls - 每个video 一个,memberscommentskeywordstranscript 一个:

getVideos(user).then((videos) => Promise.all(
  videos.map(video => getImage(video)
    .then(videoResp => Promise.all([
      getMembers(), // do you need to call these functions with `videoResp`?
      getComments(),
      getKeywords(),
      getTranscript(),
    ]))
  )
));

promise 链将解析为类似

[ [
    // video 1
    v1members,
    v1comments,
    v1keywords,
    v1transcript,
  ],
  [
    // video 2
    v2members,
    v2comments,
    v2keywords,
    v2transcript,
  ],
  // ...
]

【讨论】:

  • 有人可能会问为什么getImage() 不能与getMembers()getComments() 等等都在同一个Promise.all() 中并行化,因为它们似乎都不依赖于彼此。
  • 好问题,应该澄清一下:如果没有图像,我会中止查询。没有图像 = 无需获取所有其他内容
  • @EgorEgorov - “无图像”是指getImage() 拒绝还是必须在解析时检查返回值?
猜你喜欢
  • 2021-12-02
  • 2015-03-04
  • 2017-04-02
  • 1970-01-01
  • 2015-08-15
  • 1970-01-01
  • 2020-06-23
  • 2014-02-07
  • 2018-03-08
相关资源
最近更新 更多