问题
I have been looking thru many excellent online examples of getting a Promise to return a value in the .then(). However, there must be something different in my example that is blocking it. I am using nativescript-vue if that makes a difference, but really I think this is a Javascript question.
I have calling vue file:
var person;
personService.retrievePerson(this.id).then(function(val) {
console.log("===> received val: " + val);
person = val;
}).catch(function(err) {
console.err(err);
let message = "Unable to find matching person for id. Please try again.";
alert(message)
.then(() => {
console.log(message);
});
});
Then in my PersonService.js:
retrievePerson(id) {
new Promise(resolve => {
httpModule.request({
url: PersonAPI,
headers: headers,
method: "GET"
}).then((response) => {
// resolve();
let status = response.statusCode;
if (status === 200) {
let content = JSON.parse(response.content);
Person = JSON.parse(response.content);
console.log("===> returned [200] PersonService.retrievePerson() response: \"" + JSON.stringify(Person) + "\"")
} else if (status === 404) {
console.log("===> returned [404] ... returning null ");
}
// resolve();
}).then(() => {
console.log("===> PersonService.retrievePerson().then() has Person : " + JSON.stringify(Person));
resolve(Person);
}).catch((err) => {
console.error("retrievePerson() caught error: " + JSON.stringify(err));
});
});
}
In my console logs I can see the ===> returned [200] PersonService.retrievePerson() person JSON output, but the calling console "===> received val" is not shown. But I don't know how to get that data back to the calling class to use.
Thank you for your time, I hope you can point out what I am doing wrong here.
回答1:
you need to return the promise in your retrievePerson function:
retrievePerson(id) {
return new Promise(resolve => {
httpModule.request({
url: PersonAPI,
headers: headers,
method: "GET"
}).then((response) => {
// resolve();
let status = response.statusCode;
if (status === 200) {
let content = JSON.parse(response.content);
Person = JSON.parse(response.content);
console.log("===> returned [200] PersonService.retrievePerson() response: \"" + JSON.stringify(Person) + "\"")
} else if (status === 404) {
console.log("===> returned [404] ... returning null ");
}
// resolve();
}).then(() => {
console.log("===> PersonService.retrievePerson().then() has Person : " + JSON.stringify(Person));
resolve(Person);
}).catch((err) => {
console.error("retrievePerson() caught error: " + JSON.stringify(err));
});
});
}
回答2:
You definitely need to return the promise in your retrievePerson function. However it can also be cleaned up a lot.
You don't need the wrapping promise as you can just return the original one. You shouldn't need the double set of .then
s as well as you need to make sure you re-throw the error in the .catch
so your vue file will get a chance to catch the error rather than never resolve as it used to. I'd recommend switching from using Person
to const person
in case you run this function twice at the same time there could be a race condition as you change variable asynchronously.
I'd also like to point out one more potential issue: you aren't using the id in your request that I assume based on the console logs is supposed to be used.
function retrievePerson(id) {
return httpModule
.request({
url: PersonAPI,
headers: headers,
method: 'GET',
})
.then((response) => {
let status = response.statusCode;
if (status === 200) {
Person = JSON.parse(response.content);
console.log(
'===> returned [200] PersonService.retrievePerson() response: "' +
JSON.stringify(Person) +
'"'
);
return Person;
} else if (status === 404) {
console.log('===> returned [404] ... returning null ');
return null;
}
})
.catch((err) => {
console.error('retrievePerson() caught error: ' + JSON.stringify(err));
throw err;
});
}
来源:https://stackoverflow.com/questions/61044584/getting-js-promise-to-return-a-value