Reputation: 1501
I wanted to make then
chain but my promise was getting resolved before the inner promise execution. How can I fix this?
This code is working fine but I want to make it linear promises chain
functiontest(abc):Promise<any> {
return new Promise((resolve, reject) => {
this.nativeStorage.getItem('test')
.then(test => {
if(test == 1) {
this.function2(abc).then(tagId=>{
this.function3(tagId).then(data=>{
resolve(data)
});
});
}else {
this.function3(abc).then(data=>{
resolve(data)
});
}
},
error => {
this.function2(abc).then(tagId=>{
this.function3(tagId).then(data=>{
resolve(data)
});
});
}
)
}); }
function3
uses the results of function2
only if function2
is called otherwise function3
is called directly
Upvotes: 0
Views: 2899
Reputation: 39260
Because you seem to be stuck I think you may want to think about what the control flow of your application should be because it currently doesn't make much sense when looking at your code and then at your comments. Then test it with mocks and then test it with real functions.
Here is the simplified functionTest function that does what your code does (impossible to do what you want in the comments because that conflicts with what your code actually does). With mock thisObject (you could set thisObject with actual this when you got the control flow right).
const later = value =>
new Promise(
(resolve,reject)=>
setTimeout(
_=>resolve(value),
1000
)
)
const thisObject = {
getItem : item => {
if(item===-1){
const p = Promise.reject("nope");
p.catch(ignore=>ignore);//stops the console from shouting
console.log("in getItem, rejecting with 'nope'");
return later(p);//return rejected promise without rejection handled
}
console.log("in getItem resolving to:"+item);
return later(item);
},
function2 : item => {
console.log("in function2 with argument:",item);
return later("function2")
},
function3 : item => {
console.log("in function 3 with argument:",item);
return later("function3-"+item)
}
}
const functionTest = abc => {
//thisObject=this
return thisObject.getItem(abc)
.then(//if getItem succeeds
test =>
//call fn2 or fn3 with abc (do not pass getitem result to the functions)
// depending on getItem result
(test == 1)
? thisObject.function2(abc)//1: call function2 with abc
: thisObject.function3(abc),//not 1: cll function3 with abc
error =>//if getItem fails
//call function2 with abc and function3 with result of function2
thisObject.function2(abc)
.then(
tagId =>
thisObject.function3(tagId)
)
);
}
document.querySelectorAll("input").forEach(
(el,index)=>el.addEventListener(
"click",
e=>
functionTest(index-1)
.then(
result=>console.log("finished, result is:",result)
)
)
);
<input type="button" value="getItem that rejects">
<input type="button" value="getItem that resolves to 0">
<input type="button" value="getItem that resolves to 1">
Upvotes: 1
Reputation: 44969
Your code is really too complicated for what it is actually doing. There is no need to use new Promise
when you already get one from getItem
and you should avoid the nesting of promise handlers like .then(...then(....then()))
.
The following code should be functionally equivalent to yours:
function test(abc): Promise<any> {
return this.nativeStorage.getItem('test')
.then(test => {
if (test == 1) {
return this.function2(abc);
}
return abc;
})
.catch(() => this.function2(abc))
.then(tagId => this.function3(tagId));
}
You might also want to look into async
/await
as a way to implement asynchronous functionality in an easier manner.
Upvotes: 4
Reputation: 249576
Since you are using typescript the best way to make this code more readable is to use async/await:
class testclass {
// Dummy declaration so the code compiles
function2: (abc: any) => Promise<string>;
function3: (abc: any) => Promise<string>;
nativeStorage: {
getItem: (p: string) => Promise<number>;
}
async test(abc): Promise<any> {
try {
let test = await this.nativeStorage.getItem('test')
if (test == 1) {
let tagId = this.function2(abc);
return await this.function3(abc);
} else {
return await this.function3(abc)
}
}
catch {
let tagId = await this.function2(abc)
return await this.function3(abc)
}
}
}
Upvotes: 2