链接两个诺言

时间:2019-03-01 12:04:22

标签: javascript promise axios

我有两个诺言

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

第一个将一些数据发布到服务器,第二个查询数据以重新下载 新列表。第二个依赖于第一个。问题在于,第一个承诺会在之后实现。第二个承诺首先实现。 我如何将这两个诺言链接在一起 所以承诺2等待承诺1?

4 个答案:

答案 0 :(得分:2)

如果两个功能都不相关,但是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());

如果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.
  });

您还可以将所有内容重组为更多的原子函数,因此每个Promise都有一个特定的目标,因此可以将它们链接在一起。如果您以不同的方式嵌套结构,则甚至可以保存所有响应,然后最后返回所有。

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

答案 1 :(得分:1)

在使用then时,您可以通过在上一个解析器中创建下一个来链接Promise:

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

异步/等待,这可能会更容易:

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

答案 2 :(得分:0)

您只需将第二个Promise移到第一个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
    });
    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");
}

您还可以像这样将Promises的传递结果从一个then链接到另一个:

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

如果您想在第二个Promise中使用第一个catch的结果,或者两个sudo iptables -I INPUT -p tcp --dport 22 -s 10.8.0.0/16 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 22 -j REJECT 的逻辑相同,则这种方法会更容易。

答案 3 :(得分:-1)

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

这将等到第一个承诺解决后,再调用第二个承诺并返回结果。如果不需要.then(() => Promise2()),则不必传递结果。如果Promise1失败,则永远不会调用Promise2

注意:显然,我在最初的回复中不够详细,所以让我们对其进行详细说明。

首先,包装您的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');
      });
  }
}