【问题标题】:Observable as promise nested in promise可观察为嵌套在 promise 中的 promise
【发布时间】:2017-01-12 19:27:41
【问题描述】:

我的情况是,promisepromise 中。但是,当在包含 promise 上调用 .then 时,我得到了我内心承诺的结果。这很棒,但我不明白为什么它会起作用。为什么我可以这样做:

    this.dataService.init().then(d => console.log(d));

而不是这个:

    this.dataService.init().then(p => p.then(d => console.log(d));

数据服务

  init(){
    return this.geo.init().then( p => this.get(p.lat, p.lon));
  }

  get(lat, lon){
    let uri = `${this.baseuri}lat=${lat}&lon=${lon}&appid=${this.appid}`
   //this returns a promise
    return this.http.get(uri).toPromise()
      .then(d => d.json() || {}); 
  }

地理位置服务

  init(){
    return new Promise( this.getGeolocation );
  }

【问题讨论】:

    标签: javascript angular promise rxjs


    【解决方案1】:

    当您从.then() 处理程序内部返回一个promise 时,外部promise 和内部promise 将链接在一起。外部promise 将从内部promise 中获取它的值,外部promise 不会调用它的.then() 处理程序,直到内部promise 被解决。

    这是 Promise 的一个非常强大和有意的特性。它使您可以非常轻松地对异步操作进行排序并知道最终结果是什么。

    一个promise永远不会用另一个promise的值来解决。当它检测到您从 .then() 处理程序返回了一个 Promise 时,它​​只是链接到该 Promise 并使用该新 Promise 的值作为父 Promise 的最终值。

    事实上,你甚至不能故意让一个 promise 成为 .then() 处理程序中的解析值。在极少数情况下,您希望将已解决的值作为承诺,您必须将其包装在一个对象中(以隐藏它)并使用非承诺对象作为已解决的值进行解析。

    所以,在这一行:

    return this.geo.init().then( p => this.get(p.lat, p.lon));
    

    以下是操作顺序:

    1. 致电this.geo.init()。这会返回一个承诺,我们将调用 p1
    2. 在该承诺上调用.then() 并传递一个回调。这将注册 .then() 回调处理程序,以便稍后使用前一个承诺解析进行调用。它还返回一个新的 Promise,这是从您的函数返回的内容。我们将这个承诺称为p2。这是使其发挥作用的关键之一。
    3. 现在p1 最终解决了。这将调用在其上注册的 .then() 处理程序回调。这会调用this.get(...),它返回另一个promise p3,它是从这个.then() 处理程序内部作为返回值返回的。
    4. promise 基础结构看到您从.then() 处理程序返回了一个promise,因此它将p2 链接到p3p2 直到p3 得到解决,而p3 最终得到解决, p2 使用其解析值。完成这项工作的关键是 p1 早已解决,但 p1.then() 返回了一个新的承诺 p2 这是您的顶级函数返回的内容。并且p2 被链接到p3,所以p2 直到p2 才解析并且p2p3 获取其解析值。

    仅供参考,您可以链接到任意深度。

    【讨论】:

      【解决方案2】:

      dataService.init 函数返回一个承诺。当您调用返回承诺的函数时,传递给.then() 的参数是您在承诺解决后得到的。一个promise 无法解析并返回另一个promise 到它的.then 回调。它必须等到内部承诺首先解决。

      this.dataService.init().then(d => console.log(d));

      当您的回调收到d 时,两个promise 都已解决,d 是一个值,而不是一个promise。因此再次调用.then() 是没有意义的。

      本质上,您可以嵌套尽可能多地返回 Promise 的函数。当你调用最外层的函数时,它会等到所有的 Promise 都解决后才返回最终值。

      例如:

      const getXhrResult = () => axios.get('/some-url') // returns a promise
      
      const func1 = () => getXhrResult().then((res) => {
        console.log('Got the result')
        return result * 2 // also returns a promise
      }
      
      const func2 = () => func1().then(console.log)
      
      func2() // logs the result * 2.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-21
        • 2020-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-16
        相关资源
        最近更新 更多