问题
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?
回答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:
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:
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. 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();
回答2:
When using then, you chain promises by creating the next one inside the previous resolver:
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);
}
}
回答3:
You can simply move second Promise into then section of the first one.
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:
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.
回答4:
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()). If Promise1 fails then Promise2 is never called.
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:
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');
});
}
}
来源:https://stackoverflow.com/questions/54944306/chaining-two-promises