几天前,我发布了一个类似的问题,但是我进行了一些更改,并且对该问题的评论变得乏味,因此建议我提出一个新问题。 我的想法是我想同步执行四个方程。这些方程式内部是HTTP请求。我有两个方程可以正常工作,但是有一个方程涉及两个POST请求和一个GET请求。第二个请求依赖于第一个,第三个请求依赖于第二个。
我尝试了几种不同的方法来使其正常工作。我已经尝试过兑现诺言,兑现诺言。各种各样的事情,没有运气。我不确定我要去哪里错。
同步代码段:
this.getData1(user, userID).then(() =>
{
this.getData2(user, userID)
.then(() =>
{
this.getData3(user, lan).then(() =>
{
this.userCheck(user);
})
});
});
我有getData2和getData3。
getData1看起来像:
getData1(user: string, id: string){
console.log('grabbing CC information', id, user);
return new Promise((resolve, reject) =>
{
var status: string;
this._apiService.getAssertion(id).subscribe((data: any) =>
{
let assert = data.toString();
this._apiService.getToken(assert).subscribe((data: any) =>
{
let tkn = data.access_token.toString();
this._apiService.ccMeta(tkn, guid).subscribe((data: any) =>
{
parseString(data, (err, result) =>
{
if (err)
{
throw new Error(err);
}
else
{
status = result['entry']['content'][0]['m:properties'][0]['d:status'][0];
this.ccData.push(
{
key: 'userStatus',
value: status
})
}
});
});
});
});
resolve()
});
}
我以前也尝试过类似的方法。它也不起作用。
apiService.getAssertion(id).then(assert =>
{
return apiService.getToken(assert.toString(), user);
}).then(data =>
{
return apiService.ccMeta(data.access_token.toString(), id);
}).then(parseStringPromise).then(information =>
{
this.ccData.push(
{
key: 'userStatus',
value: information.entry
});
});
在此函数中,getAssertion函数是一个POST请求。 getToken函数是另一个POST请求,它依赖于第一个POST请求的断言。最后,ccMeta是一个get请求,它依赖于第二个POST请求中的令牌。
我希望getData1首先执行,然后执行getData2,然后执行getData3,最后执行userCheck。在getData1内部,我需要断言,然后是令牌,然后获取要同步执行的请求。上面的代码段未正确执行。在getToken公式中未正确使用该断言。
非常感谢您的帮助。
答案 0 :(得分:2)
由于这些HTTP调用实际上是可观察的,而非承诺,因此,我认为您应该使用switchMap
和getData1(user: string, id: string) {
console.log('grabbing CC information', id, user);
return new Promise((resolve, reject) => {
this._apiService.getAssertion(id)
.pipe(
switchMap((data: any) => {
let assert = data.toString();
return this._apiService.getToken(assert);
}),
switchMap((data: any) => {
let tkn = data.access_token.toString();
return this._apiService.ccMeta(tkn, guid);
}),
)
.subscribe(
data => {
parseString(data, (err, result) => {
if (err) {
reject(new Error(err));
return;
}
const status: string = result['entry']['content'][0]['m:properties'][0]['d:status'][0];
this.ccData.push({
key: 'userStatus',
value: status
});
resolve();
});
},
);
});
}
来研究可观察的组合。如果您仍然希望您的方法能够返回承诺,则它看起来可能像这样:
let const: [String] = ["Central Cooling Unit", "Split Cooling Unit", "Oven", "Refridgerator", "Dish Washer"]
var checkBox: BEMCheckBox!
var checkLabel: DefaultLabel!
var checkboxStack: DefaultStackView?
fileprivate func setupButton() {
const.forEach { (title) in
checkBox = BEMCheckBox()
checkBox.translatesAutoresizingMaskIntoConstraints = false
checkBox.tintColor = UIColor.ZAMA.offWhite
checkBox.onCheckColor = UIColor.ZAMA.primary
checkBox.onFillColor = UIColor.ZAMA.tabColor
checkBox.onTintColor = UIColor.ZAMA.primary
checkBox.onAnimationType = .flat
checkBox.heightAnchor.constraint(equalToConstant: 25).isActive = true
checkBox.widthAnchor.constraint(equalToConstant: 25).isActive = true
checkLabel = UILabel()
checkLabel.text = title
checkLabel.textColor = .black
checkLabel.fontSize = 15
checkboxStack = UIStackView(arrangedSubviews: [centralCoolingCheckbox, centralCoolingText])
checkboxStack?.axis = .horizontal
checkboxStack?.spacing = 4
checkboxStack?.alignment = .fill
checkboxStack?.distribution = .fill
}
}
fileprivate func layout() {
view.addSubview(scrollView)
hideKeyboardWhenTappedAround()
setupButton()
stack = UIStackView(arrangedSubviews: [checkboxStack ?? DefaultStackView()])
stack.axis = .vertical
stack.distribution = .fillEqually
stack.spacing = 8
view.addSubview(stack)
stack.anchor(top: contentView.topAnchor, left: contentView.leftAnchor, bottom: nil, right: contentView.rightAnchor, paddingTop: 4, paddingLeft: 8, paddingBottom: 0, paddingRight: 8, width: 0, height: 0, enableInsets: false)
}