Javascript 如何创建一个处理两个承诺然后返回一个承诺的类?

Javascript 如何创建一个处理两个承诺然后返回一个承诺的类?,javascript,react-native,es6-promise,Javascript,React Native,Es6 Promise,我想创建一个类,其职责是轮询数据源,将信息整理成一个“警报”对象数组,然后将这些警报的子集传递给需要它们的任何其他类 因为轮询是异步进行的(我正在从web服务请求数据),所以我假设我实际需要返回的是一个承诺,当该承诺实现时,将给出警报对象的正确子集 但很明显,我不明白怎么做,因为应该返回承诺的方法会返回其他东西 这是到目前为止我的代码。如您所见,我正在尝试将承诺存储在实例属性中,然后检索它: export class AlertCollection { constructor() {

我想创建一个类,其职责是轮询数据源,将信息整理成一个“警报”对象数组,然后将这些警报的子集传递给需要它们的任何其他类

因为轮询是异步进行的(我正在从web服务请求数据),所以我假设我实际需要返回的是一个承诺,当该承诺实现时,将给出警报对象的正确子集

但很明显,我不明白怎么做,因为应该返回承诺的方法会返回其他东西

这是到目前为止我的代码。如您所见,我正在尝试将承诺存储在实例属性中,然后检索它:

export class AlertCollection {

  constructor() {
    this.alerts = null;
  }

  // poll the data sources for alert data; store a promise that resolves
  // to an array of alerts
  poll() {
    this.alerts = this.pollTeapot()
                    .then( (arr) => {this.pollDeliverance(arr);} );

  }                                                                                                  

  // return a promise that fulfils to an array of the alerts you want
  filteredAlerts(filter) {
    return this.alerts; // not filtering for now
  }                                                                                                  

  // return a promise that fulfills to the initial array of alerts
  pollTeapot() {

    let process = (json) => {
      json2 = JSON.parse(json);
      return json2.map( (a) => new Alert(a) );
    };                                                                                               

    message = new MessageHandler("teapot", "alerts")
    return message.request().then( (json) => {process(json);} );
  }

  // Modify the alerts based on the response from Deliverance.
  // (But for the time being let's not, and say we did.)
  pollDeliverance(alerts) {
    return alerts;
  }

}
message.request()
从web服务返回承诺。这很有效。如果我在
pollTeapot()
中快照
进程
函数,我会得到正确的数据

但是,如果我从
filteredAlerts()
快照返回值,我就不会得到它。我也没有得到null(这至少是有意义的,尽管它是错误的。)我得到了类似于
{{u45:0、\u81:0、\u65:null、\u54:null}


在这一点上,任何指点都将不胜感激。(顺便说一句,这是React Native,如果有帮助的话。)

这将是一个很难描述的例子-我有一个工作示例,但它很复杂,因为我必须“模拟”所有异步部分,并使用
函数
类,而不是
关键字-但想法是一样的


这个答案有两个部分

  • 警报
    存储为实例变量没有意义。它们是异步的,在异步调用完成之前不会存在

  • 您需要将所有行为链接到对
    poll


  • 一般来说,你会像这样把承诺彼此联系在一起

    functionWhichReturnsPromise()
          .then(functionPointer)
          .then(function(result){
               // some functionality, which can return anything - including another promise
          });
    
    所以你的代码最终看起来像

    var alertCollection = new AlertCollection()
    alertCollection.poll().then(function(alerts){
        //here alerts have been loaded, and deliverance checked also!
    });
    
    该类的代码将遵循以下行:

    export class AlertCollection {
    
      constructor() {
      }
    
      // poll the data sources for alert data; store a promise that resolves
      // to an array of alerts
      poll() {
        return this.pollTeapot()
                   .then(filteredAlerts)
                   .then(pollDeliverance);
    
      }                                                                                                  
    
      // return a promise that fulfils to an array of the alerts you want
      filteredAlerts(alerts) {
        return alerts; // not filtering for now
      }                                                                                                  
    
      // return a promise that fulfills to the initial array of alerts
      pollTeapot() {
    
        let process = (json) => {
          json2 = JSON.parse(json);
          return json2.map( (a) => new Alert(a) );
        };                                                                                               
    
        message = new MessageHandler("teapot", "alerts")
        return message.request().then(process);
      }
    
      // Modify the alerts based on the response from Deliverance.
      // (But for the time being let's not, and say we did.)
      pollDeliverance(alerts) {
        return alerts;
      }
    
    }
    
    一些注释

    • filteredAlerts
      可以执行任何您喜欢的操作,只要它返回一个结果数组
    • pollDeliverance
      还可以执行任何您喜欢的操作—如果它需要调用另一个异步方法,请记住返回一个承诺,该承诺将解析为一组警报—可能会根据异步调用的结果进行更新

    我创建了一个JSFIDLE来演示这一点——使用一个简单的
    getJSON
    调用来复制其中一些的异步特性。正如我所提到的,这是一个复杂的过程,但它演示了以下过程:


    活生生的例子:

    我不确定我是否完全理解了您的问题,但我将尝试为您提供一个通用的解决方案,一个接一个地链接承诺

    someAsyncFunction().then(dataFromAsync1 => {
        return anotherAsyncFunction(dataFromAsync1).then(dataFromAsync2 => {
            return doSomethingWithData(dataFromAsync1, dataFromAsync2);
        });
    });
    

    我大体上了解你的问题,但是你的头衔会议处理了2个承诺,我看不出这是在哪里-因为你只是在处理一个-
    message.request()
    bit如果你想连锁承诺,你应该看看ES6中的
    Promise.all()
    。@jamice in
    poll()
    我在连锁
    pollTeapot())
    然后
    pollDeliverance()
    ;你是对的,目前后者没有做任何事情,但是如果我不能让它为其中一个工作,那么添加另一个也没有多大意义…@AndyJones啊,我看到
    pollDeliverance
    发出另一个异步调用并更新
    Alert
    的?@Hinrich——如果我理解正确,
    Promise.all()
    是否会同时调用这两种服务?我不想这样。你需要记住从
    内部的回调中
    返回
    ,然后
    否则你将无法将事情链接到这里的问题是,我需要能够多次调用
    filteredAlerts()
    以对返回的结果进行不同的筛选。我不想每次都要轮询数据源。这就是为什么我想要一个有自己状态的类;如果没有这些,我真的不认为上课有多大意义。@AndyJones那是我的错误,我应该改变论点,从你的原始答案返回(见更新的答案)。基本上,参数是
    警报
    实例,您可以按自己喜欢的方式筛选并返回该数组。看看我的例子,我确实做到了这一点。听起来好像你在说,我不能让一个班级只进行一次民意调查,就可以多次兑现承诺。这是一个极大的限制。(我的想法是存储承诺,而不是实际结果。)@AndyJones我不确定我是否遵守。您当然可以缓存承诺的结果,但不要期望它在异步解决之前就存在。无论如何,在这里,你将非常接近于一个最受欢迎的dupe close问题,这是一个很难回答的问题,而且相当复杂。如果你想的话,请随时与我聊天!(只是出去吃午饭,所以可能在20分钟内没有反应)