我想建立then
链,但我的承诺在内部承诺执行之前得到解决。我该如何解决这个问题?
此代码工作正常,但我想将其设为线性承诺链
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
被调用时, function2
才会使用function2
的结果,否则会直接调用function3
答案 0 :(得分:3)
您的代码实际上太复杂了。当您从new Promise
获得getItem
时,不需要使用.then(...then(....then()))
,并且应该避免嵌套像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));
}
这样的承诺处理程序。
以下代码在功能上应与您的代码相同:
async
您可能还希望将await
/ {{1}}作为一种以更简单的方式实现异步功能的方法。
答案 1 :(得分:2)
由于您使用的是typescript,因此使代码更具可读性的最佳方法是使用async / await:
<form [formGroup]="myForm">
Playername: <input formControlName="player" type="text" ><br>
</form>
TotalPoint: 14 <br>
totalPointInTournament: 9 <br>
totalPointInTournament: 5 <br>
<pre>
{{myForm.value |json}}
</pre>
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormBuilder, Validators, FormArray,
ReactiveFormsModule, AbstractControl } from '@angular/forms';
@Component({
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.css']
})
export class ContactComponent implements OnInit {
myForm: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
this.myForm = this.fb.group({
player: new FormControl(''),
totalPoint: '14',
weeks: this.fb.array([
this.fb.group({
totalPointInTournament: '9',
matches: this.fb.array([
this.fb.group({
point: '5'
}),
this.fb.group({
point: '4'
})
])
}),
this.fb.group({
totalPointInTournament: '5',
matches: this.fb.array([
this.fb.group({
point: '3'
}),
this.fb.group({
point: '2'
})
])
})
])
}
);
this.updateStats();
}
updateStats() {
this.myForm.get('weeks').valueChanges.subscribe(val => {
// Calculate total point here..
console.log('val' + JSON.stringify(typeof (val)));
});
}
}
答案 2 :(得分:1)
因为您似乎陷入困境我认为您可能想要考虑应用程序的控制流应该是什么,因为在查看您的代码然后在您的评论中它目前没有多大意义。然后用模拟测试它,然后用真实函数测试它。
这是简化的functionTest函数,它可以完成代码所做的工作(不可能在注释中执行您想要的操作,因为这与您的代码实际执行的操作相冲突)。使用mock thisObject(你可以在控制流正确时将thisObject设置为this)。
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">