Javascript 可观察为嵌套在承诺中的承诺

Javascript 可观察为嵌套在承诺中的承诺,javascript,angular,promise,rxjs,Javascript,Angular,Promise,Rxjs,我所处的场景是,我在一个承诺中有一个承诺。然而,当调用。然后包含承诺时,我得到了我内心承诺的结果。这很好,但我不明白它为什么有效。为什么我可以这样做: this.dataService.init().then(d => console.log(d)); 与此相反: this.dataService.init().then(p => p.then(d => console.log(d)); 数据服务 init(){ return this.geo.

我所处的场景是,我在一个
承诺
中有一个
承诺
。然而,当调用
。然后
包含
承诺
时,我得到了我内心承诺的结果。这很好,但我不明白它为什么有效。为什么我可以这样做:

    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 );
  }
地理定位服务

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

当您从
.then()
处理程序内部返回承诺时,外部承诺和内部承诺将链接在一起。然后,外部承诺将从内部承诺获取其值,并且在内部承诺得到解决之前,外部承诺不会调用它的
.then()
处理程序

这是承诺的一个非常强大和有意的特征。它允许您非常轻松地对异步操作进行排序,并知道最终结果是什么

承诺永远不会与另一个承诺的价值相冲突。当它检测到您从
.then()
处理程序返回承诺时,它只是链接到该承诺,并使用该新承诺的值作为父承诺的最终值

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

因此,在这方面:

return this.geo.init().then( p => this.get(p.lat, p.lon));
以下是操作顺序:

  • 调用
    this.geo.init()
    。如果返回一个承诺,我们将调用
    p1
  • 对该承诺调用
    。然后()
    ,并向其传递回调。这将注册
    .then()
    回调处理程序,以便稍后使用前面的承诺解析调用。它还返回一个新的承诺,即从函数返回的承诺。我们将这一承诺称为p2。这是使其工作的关键之一
  • 现在,
    p1
    最终解决。这将调用在其上注册的
    .then()
    处理程序回调。这将调用
    This.get(…)
    ,它返回另一个promise
    p3
    ,该promise从
    内部返回。然后()
    处理程序作为返回值
  • promise基础结构会看到您从
    .then()
    处理程序返回了一个承诺,因此它将
    p2
    链接到
    p3
    ,并且
    p2
    直到
    p3
    完成解析,并且当
    p3
    最终得到解析时,才会得到解析。这项工作的关键是
    p1
    早就解决了,但是
    p1。然后()
    返回了一个新的承诺
    p2
    ,这就是顶级函数返回的。而
    p2
    被链接到
    p3
    ,因此
    p2
    p2
    进行解析之前不会解析,
    p2
    p3
    获取其解析值

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

    当您从
    处理程序内部返回承诺时。然后()
    处理程序将外部承诺和内部承诺链接在一起。然后,外部承诺将从内部承诺获取其值,并且在内部承诺得到解决之前,外部承诺不会调用它的
    .then()
    处理程序

    这是承诺的一个非常强大和有意的特征。它允许您非常轻松地对异步操作进行排序,并知道最终结果是什么

    承诺永远不会与另一个承诺的价值相冲突。当它检测到您从
    .then()
    处理程序返回承诺时,它只是链接到该承诺,并使用该新承诺的值作为父承诺的最终值

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

    因此,在这方面:

    return this.geo.init().then( p => this.get(p.lat, p.lon));
    
    以下是操作顺序:

  • 调用
    this.geo.init()
    。如果返回一个承诺,我们将调用
    p1
  • 对该承诺调用
    。然后()
    ,并向其传递回调。这将注册
    .then()
    回调处理程序,以便稍后使用前面的承诺解析调用。它还返回一个新的承诺,即从函数返回的承诺。我们将这一承诺称为p2。这是使其工作的关键之一
  • 现在,
    p1
    最终解决。这将调用在其上注册的
    .then()
    处理程序回调。这将调用
    This.get(…)
    ,它返回另一个promise
    p3
    ,该promise从
    内部返回。然后()
    处理程序作为返回值
  • promise基础结构会看到您从
    .then()
    处理程序返回了一个承诺,因此它将
    p2
    链接到
    p3
    ,并且
    p2
    直到
    p3
    完成解析,并且当
    p3
    最终得到解析时,才会得到解析。这项工作的关键是
    p1
    早就解决了,但是
    p1。然后()
    返回了一个新的承诺
    p2
    ,这就是顶级函数返回的。而
    p2
    被链接到
    p3
    ,因此
    p2
    p2
    进行解析之前不会解析,
    p2
    p3
    获取其解析值

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

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