可承诺嵌套在promise中的promise

时间:2017-01-12 19:27:42

标签: javascript angular promise rxjs

我在promise内有promise的情况。但是,当在.then包含promise时,我会得到我内心承诺的结果。哪个好,但我不明白为什么它有效。我为什么要这样做:

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

而不是:

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

的DataService

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

2 个答案:

答案 0 :(得分:3)

当你从.then()处理程序中返回一个promise时,外部promise和内部promise将链接在一起。然后外部承诺将从内部承诺中获得其价值,而外部承诺将不会称之为.then()处理程序,直到内部承诺得到解决。

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

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

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

所以,在这一行:

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

以下是操作顺序:

  1. 致电this.geo.init()。这将返回一个承诺,我们将调用p1
  2. 在该承诺上调用.then()并向其传递回调。这将注册.then()回调处理程序,以便稍后使用先前的promise解析。它还返回一个新的promise,它是从你的函数返回的。我们将此承诺称为p2。这是允许它工作的关键之一。
  3. 现在p1最终解决了。这会调用在其上注册的.then()处理程序回调。这将调用this.get(...),它返回从此p3处理程序内部返回的另一个promise .then()作为返回值。
  4. 承诺基础架构看到您从.then()处理程序返回了一个承诺,因此它将p2链接到p3并且p2p3之前无法解析当p3最终得到解决时,p2会使用其已解析的值。使这项工作的关键是p1很久以来已经解决,但p1.then()返回了新的承诺p2,这是您的顶级函数返回的。 p2p3链接到p2,因此只有p2p2p3获得其解析后的价值才能解析{。}}。
  5. 仅供参考,您可以链接到任意深度。

答案 1 :(得分:1)

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

.then

当你的回调收到this.dataService.init().then(d => console.log(d));时,两个承诺都已经解决,d是一个值,而不是一个承诺。因此,再次呼叫d是没有意义的。

基本上,您可以根据需要嵌套返回承诺的函数。当你调用最外面的函数时,它会等到所有的promises都解决后再返回最终值。

例如:

.then()