简体   繁体   English

链接两个诺言

[英]Chaining two promises

I have two promises 我有两个承诺

    const promise_1 = this.connection.insertPatientToDataBase(Store.getPotentialPatientID())
      .then(ting => {
        console.log(ting);
        Dispatcher.dispatch({
        actionType: Constants.CHANGE_POTENTIAL_PATIENT_PASSWORD,
        payload: ting.data.password
      })})
      .catch(error => {console.log(error)});

    const promise_2 = this.connection.getAllPatientData()
      .then( function(response) {
        console.log("Dispatrinc a new server call")
        console.log(response.data)
       Dispatcher.dispatch({
        actionType: Constants.CHANGE_ALL_PATIENTS,
        payload: response.data
      })})
      .catch(error => console.log(error))


      console.log("Done");
  }

the first one will post some data to the server, and the second one queries the data to redownload the new list. 第一个将一些数据发布到服务器,第二个查询数据以重新下载新列表。 The second one is dependent on the first one. 第二个依赖于第一个。 Problem is that the first promise is fulfilled after. 问题在于,第一个承诺会在之后实现。 Second promise is fulfilled first. 第二个承诺首先实现。 How can I chain these two promises together so promise 2 waits on promise 1? 我如何将这两个诺言链接在一起,以便诺言2等待诺言1?

If both functions are unrelated, but promise_1 has to resolve first so that the patient exists, you can just wrap the promise creation inside a function and only call the promise_2 creation when promise_1 resolves: 如果两个功能都不相关,但是必须首先解决promise_1以便患者存在,那么您可以将promise创建包装在一个函数中,并且只有在promise_1解决时才调用promise_2创建:

const promise_1 = () => this.connection.insertPatientToDataBase(Store.getPotentialPatientID())
  .then(ting => {
    console.log(ting);
    Dispatcher.dispatch({
    actionType: Constants.CHANGE_POTENTIAL_PATIENT_PASSWORD,
    payload: ting.data.password
  })})
  .catch(error => {console.log(error)});

const promise_2 = () => this.connection.getAllPatientData()
  .then( function(response) {
    console.log("Dispatrinc a new server call")
    console.log(response.data)
   Dispatcher.dispatch({
    actionType: Constants.CHANGE_ALL_PATIENTS,
    payload: response.data
  })})
  .catch(error => console.log(error));

  promise_1().then( response => promise_2());

If promise_2 relies on the results of promise_1 to run, for example if promise_1 will return the patient id and you need that id to run promise_2 and only the result of promise_2 has to be available after both resolve, then you can modify the above a tiny bit to pass the parameter: 如果promise_2依赖于promise_1的运行结果,例如,如果promise_1将返回患者ID,并且您需要该ID来运行promise_2,并且在两个解析之后仅promise_2的结果必须可用,那么您可以对上面的内容进行一些修改传递参数的位:

const promise_1 = () => this.connection.insertPatientToDataBase(Store.getPotentialPatientID())
      .then(ting => {
        console.log(ting);
        Dispatcher.dispatch({
        actionType: Constants.CHANGE_POTENTIAL_PATIENT_PASSWORD,
        payload: ting.data.password
      })})
      .catch(error => {console.log(error)});

const promise_2 = patient_id => this.connection.getAllPatientData( patient_id )
      .then( function(response) {
        console.log("Dispatrinc a new server call")
        console.log(response.data)
       Dispatcher.dispatch({
        actionType: Constants.CHANGE_ALL_PATIENTS,
        payload: response.data
      })})
      .catch(error => console.log(error));

promise_1()
  .then( patient_id => promise_2( patient_id ))
  .then( patient_data => {
    // handle patient data.
  });

You could also restructure everything into more atomic functions, so each promise has one specific goal, so you can chain them all together. 您还可以将所有内容重组为更多的原子函数,因此每个Promise都有一个特定的目标,因此可以将它们链接在一起。 If you nest the structure differently, you can even save all of the responses and return all fo then at the end. 如果您以不同的方式嵌套结构,则甚至可以保存所有响应,然后最后返回所有。

const create_patient_id = () => this.connection.insertPatientToDataBase(Store.getPotentialPatientID());

const create_patient = patient_id => Dispatcher.dispatch({
    actionType: Constants.CHANGE_POTENTIAL_PATIENT_PASSWORD,
    payload: patient_id.data.password
});

const get_patients = () => this.connection.getAllPatientData();

const update_patients = patients => Dispatcher.dispatch({
    actionType: Constants.CHANGE_ALL_PATIENTS,
    payload: patients.data
})

const workflow = () => create_patient_id()
  .then( create_patient );
  .then( get_patients )
  .then( update_patients );

 workflow();

When using then , you chain promises by creating the next one inside the previous resolver: 使用then ,您可以通过在上一个解析器中创建下一个来链接诺言:

const promise_1 = this.connection.insertPatientToDataBase(Store.getPotentialPatientID())
  .then(ting => {
    console.log(ting);

    Dispatcher.dispatch({
      actionType: Constants.CHANGE_POTENTIAL_PATIENT_PASSWORD,
      payload: ting.data.password
    });

    return this.connection.getAllPatientData();
  })
  .then(response => {
    console.log("Dispatrinc a new server call");
    console.log(response.data);

    Dispatcher.dispatch({
      actionType: Constants.CHANGE_ALL_PATIENTS,
      payload: response.data
    });
  })
  .catch(error => {console.log(error)});

whith async/await this may be easier on the eyes: 异步/等待,这在眼睛上可能会更容易:

async insertAndGet() {
  try {
    const ting = await this.connection.insertPatientToDataBase(Store.getPotentialPatientID());

    console.log(ting);

    Dispatcher.dispatch({
      actionType: Constants.CHANGE_POTENTIAL_PATIENT_PASSWORD,
      payload: ting.data.password
    };

    const response = await this.connection.getAllPatientData();

    console.log("Dispatrinc a new server call");
    console.log(response.data);

    Dispatcher.dispatch({
      actionType: Constants.CHANGE_ALL_PATIENTS,
      payload: response.data
    })};
  } catch (error) {
    console.log(error);
  }
}

You can simply move second Promise into then section of the first one. 您可以简单地将第二个Promise移到第一个Promise then部分。 If first promise fails, second one is not executed, if it resolves successfully - second one will commence. 如果第一个承诺失败,则第二个承诺不会成功执行,如果它成功解决-第二个承诺将开始。 Code will look something like this: 代码将如下所示:

const promise_1 = this.connection.insertPatientToDataBase(Store.getPotentialPatientID())
  .then(ting => {
    console.log(ting);
    Dispatcher.dispatch({
      actionType: Constants.CHANGE_POTENTIAL_PATIENT_PASSWORD,
      payload: ting.data.password
    });
    const promise_2 = this.connection.getAllPatientData()
      .then(response => {
        console.log("Dispatrinc a new server call");
        console.log(response.data);
        Dispatcher.dispatch({
          actionType: Constants.CHANGE_ALL_PATIENTS,
          payload: response.data
        });
    })
    .catch(console.log);
  })
  .catch(console.log);

  console.log("Done");
}

You can also chain Promises passing results from one then to another like this: 你也可以连接Promises通过结果从一个then到另一个像这样:

SomePromiseFunc().then(result1 => SomeOtherPromiseFunc(result1)).then(result2=> doSmth(result2)).catch();

This way could be easier if you want to use result of 1st Promise inside the second one or if catch logic is the same for both of them. 如果要在第二个内部使用第一个Promise结果,或者两个catch逻辑都相同,则这种方法可能会更容易。

Promise1()
  .then(response => Promise2(response))
  .catch(err => {
    // do something with error
  });

This waits until the first promise is resolved, then calls the second promise with the result. 这将等到第一个承诺解决后,再调用第二个承诺并返回结果。 You don't have to pass along the result, if you don't need it .then(() => Promise2()) . 如果不需要,则不必传递结果.then(() => Promise2()) If Promise1 fails then Promise2 is never called. 如果Promise1失败,则永远不会调用Promise2

Note: Apparently I wasn't verbose enough in my initial response, so let's break it down a little better. 注意:显然我在最初的答复中不够详细,所以让我们将其分解得更好一些。

First, wrap your promise calls so you can provide the extra functionality to each: 首先,包装您的Promise调用,以便为每个提供额外的功能:

class MyCustomClass {
  createNewPatient() { // maybe you pass it in? maybe it's always there?
    // Guessing Store is outside the class, but available
    return this.connection.insertPatientToDataBase(Store.getPotentialPatientID())
      .then(ting => {
        console.log(ting);
        // Guessing Dispatcher and Constants are outside the class, but available
        Dispatcher.dispatch({
          actionType: Constants.CHANGE_POTENTIAL_PATIENT_PASSWORD,
          payload: ting.data.password
        });
      })
      .catch(error => {console.log(error)});
  }

  reloadResults() {
    return this.connection.getAllPatientData()
      .then( function(response) {
        console.log("Dispatrinc a new server call")
        console.log(response.data)
        // Guessing Dispatcher and Constants are outside the class, but available
        Dispatcher.dispatch({
          actionType: Constants.CHANGE_ALL_PATIENTS,
          payload: response.data
        });
      })
      .catch(error => {console.log(error)});
  }

  // What you seem to be looking for
  createAndReload() {
    return this.createNewPatient()
      .then(() => this.reloadResults())
      .then(() => {
        console.log('done');
      });
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM