Here is the code:
function f1(id) {
return new Promise((resolve, reject) => {
if (id === 123132) {
resolve([{id:1,name:"John"}, {id:10, name:"Chris"}])
} else {
reject(new Error("f1 fails - can't find info for id"))
}
})
}
function f2(gender) {
return new Promise((resolve, reject) => {
if (gender === "FEMALE") {
resolve([{id:6, name:"Stacy"}, {id:1, name:"John"}, {id:13, name:"Veronica"}])
} else {
reject(new Error("f2 Fails"))
}
})
}
function Test(User, N){
return new Promise((resolve, reject)=>{
f1(User.id).catch(err=>{
console.log(err.message)
//this api returns an error, so call the other one
f2(User.gender).catch(err=>{
console.log(err.message)
reject(new Error("Both api calls have failed"))
}).then(res=>{
if (res.length<N){
reject(new Error("Not Enough Data..."))
} else {
console.log("We are here..")
console.log(res)
resolve(res.slice(0,N).map(item=>item.name))
}
})
})
.then(res1=>{
console.log("We should not be here but we are...")
console.log(res1)
if (res1.length<N){
f2(User.gender).catch(err=>{
console.log(err.message)
// reject(new Error("Not Enough Data"))
throw new Error("Not Enough Data")
}).then(res2=>{
res3 = filterDups2(res1, res2)
res3.length>=N ? resolve(res3.slice(0,N).map(item=>item.name)) :
reject(new Error("Not Enough Data"))
})
} else {
console.log("Why are we not here...")
resolve(res1.slice(0,N).map(item=>item.name))
}
})
})
}
function filterDups2(list1, list2){
jointRes = [...list1, ...list2]
ans = Array.from(new Set(jointRes.map(item=>JSON.stringify(item)))).map(item=>JSON.parse(item))
return ans
}
let user = { id: 123, gender: "FEMALE" }
let result = Test(user, 2)
result.then(res=> console.log(res)).catch(err=> {
console.log("Inside result...")
console.log(err.message)
})
Here is the output on the console:
f1 fails - can't find info for id
We should not be here but we are...
undefined
We are here..
[
{ id: 6, name: 'Stacy' },
{ id: 1, name: 'John' },
{ id: 13, name: 'Veronica' }
]
[ 'Stacy', 'John' ]
(node:2968) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'length' of undefined
at /Users/daanishraj/Desktop/Front-End-Work/WDB-Feb-2021/JavaScript/Practice/interviews/zalando/forStackOverflow.js:50:20
(Use `node --trace-warnings ...` to show where the warning was created)
(node:2968) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:2968) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
I don't understand why we have the following two things on the console
We should not be here but we are...
undefined
showing up before these outputs:
We are here..
[
{ id: 6, name: 'Stacy' },
{ id: 1, name: 'John' },
{ id: 13, name: 'Veronica' }
]
[ 'Stacy', 'John' ]
I understand that because the outermost catch block i.e. f1(U.id).catch() is resolved, this would make us step into the outermost then block i.e.f1(U.id).then(). But the sequence of these outputs suggest that we are stepping into the then block before the catch block is resolved.
- Why is this the case?
- Since we are indeed stepping into the then block, once res1 is deemed
undefined
, why doesn't the control move to the bottom of the then block where we would outputWhy are we not here...
?
In general, if you could throw some light on the sequence of execution here, that would be great!