I am coding this chained promises.
First, when a button is clicked, it checks if a file url exists:
If not, it rejects, and then the response status is shown in an alert.
If yes, then it updates the DB via a webapi, then update the react state.
The problem I faced is, even I rejected in validateResponse function, it still run the next then.
I think it should go to the catch directly.
Besides, the below code to call webapi seems not good, a promise inside a then, etc. also the whole code seems unclear? is it a better way to do so?
onClick: (event, row) => {
function validateResponse(response) {
if (!response.ok) { // assume it is the reject case.
console.log("file not ready");
return Promise.reject(response.statusText);
} else {
window.open(response.url, '_blank', 'location=yes,height=500,width=600,scrollbars=no,status=yes')
return response;
}
}
fetch(row.fileurl, {
method: 'HEAD'
})
.then(validateResponse)
.then(console.log("== this line not printed, due to rejected."))
.then(row.linked = 1)
.then(
fetch(this.server_url+'/file/linked', { method: 'POST', body: JSON.stringify(row), headers: { 'Content-Type': 'application/json' }, })
.then(res => {
console.log("== it should be rejected!, why printed this line2")
if (res.status==200) {
this.setState({ row });
} else {
row.checked = 0;
throw Error(res.status);
}
})
)
.catch(function (error) {
alert("Sorry, the file is not avaliable yet")
});
}
One more question:
.then(() => row.linked = 1)
.then(() => fetch(this.server_url+'/file/linked', { method: 'POST', body: JSON.stringify(row), headers: { 'Content-Type': 'application/json' }, })
how to combine this into one?
.then(() => row.linked = 1 && fetch(this.server_url+'/file/linked', { method: 'POST', body: JSON.stringify(row), headers: { 'Content-Type': 'application/json' }, })
is it a better/correct way to do so?
Returning the Promise.reject
should make it work.
Issue is that when you don't specify a return value in a .then
it will resolve the promise with an undefined value by default.
In your case, you should change your validateResponse
so it returns the rejected promise:
return Promise.reject(response.statusText);
Check this for more info.
=================
Edit: Try with this code
onClick: (event, row) => {
function validateResponse(response) {
if (!response.ok) { // assume it is the reject case.
console.log("file not ready");
return Promise.reject(response.statusText);
} else {
window.open(response.url, '_blank', 'location=yes,height=500,width=600,scrollbars=no,status=yes')
return response;
}
}
fetch(row.fileurl, {
method: 'HEAD'
})
.then(validateResponse)
.then(() => console.log("== this line not printed, due to rejected."))
.then(() => row.linked = 1)
.then(() => fetch(this.server_url+'/file/linked', { method: 'POST', body: JSON.stringify(row), headers: { 'Content-Type': 'application/json' }, })
.then(res => {
console.log("== it should be rejected!, why printed this line2")
if (res.status==200) {
this.setState({ row });
} else {
row.checked = 0;
throw Error(res.status);
}
})
)
.catch(function (error) {
alert("Sorry, the file is not avaliable yet")
});
}
========================
Edit2: .then
accepts a function as callback. This means you can put it in one big function if you want:
onClick: (event, row) => {
function validateResponse(response) {
if (!response.ok) { // assume it is the reject case.
console.log("file not ready");
return Promise.reject(response.statusText);
} else {
window.open(response.url, '_blank', 'location=yes,height=500,width=600,scrollbars=no,status=yes')
return response;
}
}
fetch(row.fileurl, {
method: 'HEAD'
})
.then(validateResponse)
.then(() => {
console.log("== this line not printed, due to rejected.");
row.linked = 1;
return fetch(this.server_url+'/file/linked', { method: 'POST', body: JSON.stringify(row), headers: { 'Content-Type': 'application/json' }, })
.then(res => {
console.log("== it should be rejected!, why printed this line2")
if (res.status==200) {
this.setState({ row });
} else {
row.checked = 0;
throw Error(res.status);
}
})
})
.catch(function (error) {
alert("Sorry, the file is not avaliable yet")
});
}
You aren't calling your second fetch in a callback and that is causing the fetch to fire immediately .
function someFunc() {
// You are invoking the second fetch immediately
fetch("example.com")
.then(validate)
.then(fetch("somewhere.com"))
// You need to invoke it as a callback
fetch("example.com")
.then(validate)
.then(() => fetch("somewhere.com"))
// Or with non-arrow
fetch("example.com")
.then(validate)
.then(function() {
return fetch("somewhere.com");
});
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.