Angular 强制Javascript/节点等待服务完成
我试图调用一个服务,并用结果值构建一个对象。如果我知道我在做什么,我也会处理错误,但我不知道如何处理。不幸的是,代码开始服务调用,然后在服务调用完成之前返回到服务后面的语句 我不在乎它有多么不现代、不酷或是其他什么,我希望这段代码能等待服务的成功或失败。无论如何,我在应用程序中所做的一切都取决于这项服务的成功 我都尝试设置断点并添加日志语句Angular 强制Javascript/节点等待服务完成,angular,typescript,Angular,Typescript,我试图调用一个服务,并用结果值构建一个对象。如果我知道我在做什么,我也会处理错误,但我不知道如何处理。不幸的是,代码开始服务调用,然后在服务调用完成之前返回到服务后面的语句 我不在乎它有多么不现代、不酷或是其他什么,我希望这段代码能等待服务的成功或失败。无论如何,我在应用程序中所做的一切都取决于这项服务的成功 我都尝试设置断点并添加日志语句 import { Injectable, Injector } from '@angular/core'; import { HttpClient, Htt
import { Injectable, Injector } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { UUID } from 'angular2-uuid';
import { Constants } from './constants';
@Injectable()
export class AppConfigService {
private constants = null;
constructor (private injector: Injector) { }
loadAppConfig() {
let http = this.injector.get(HttpClient);
/*
return http.get('/assets/app-config.json')
.toPromise()
.then(data => {
this.appConfig = data;
})
*/
if(this.constants != null) {
console.log('@@WOODSMAN environmentData is not null');
console.log('@@WOODSMAN lazy loaded environmentData already is '+JSON.stringify(this.constants));
} else {
console.log('@@WOODSMAN environmentData is null');
let headerValues = new HttpHeaders()
.set('Accept-Encoding', 'application/json; charset=UTF-8')
.set('Content-Type', 'application/json; charset=UTF-8')
.set('SC_TRACE_ID', UUID.UUID());
let httpOptions = {
headers: headerValues
};
console.log('@@WOODSMAN: Waiting for environment info from service call');
let appConfig = http.post("/proxy/report/getEnvironment", "",httpOptions)
.toPromise().then(data => {
this.setConstants(data);
});
/*
while(this.environmentData == null) {
console.log('@@@WOODSMAN appConfig is null even after service call');
}
*/
if(this.constants == null) {
console.log('@@@WOODSMAN appConfig is null even after service call');
}
};
console.log('@@WOODSMAN: environmentData result = '+JSON.stringify(this.constants));
}
private setConstants(environmentData) {
console.log('@@WOODSMAN calling environmentData='+JSON.stringify(environmentData));
this.constants = new (environmentData);
}
get config() {
//return this.appConfig;
if(this.constants==null) {
console.log('@@WOODSMAN Call to config found null appConfig. Calling the load');
this.loadAppConfig();
if(this.constants==null) {
console.log('@@WOODSMAN Second call to config still found null appConfig.');
}
}
console.log('@@WOODSMAN environment.salesconnectURL' + this.constants["baseUrl"]);
console.log('@@WOODSMAN environment.salesconnectURL' + this.constants["homepageURL"]);
console.log('@@@WOODSMAN end getConstants ');
return this.constants;
}
}
我在浏览器日志中看到这两行的顺序(它们之间没有日志语句)。
“@@WOODSMAN:正在等待来自服务调用的环境信息”
“@@@WOODSMAN appConfig即使在服务调用之后也是空的”
我尝试将其包装在一个异步函数中并添加一个wait语句,但它仍然忽略了这一点,并没有等待完成
由于服务需要几毫秒才能完成,因此我尝试在上面添加一个while循环,以等待设置该值。但是,由于不允许服务处理程序满足循环条件,因此它变成了一个永久循环
***更新
我尝试添加一个提供同步功能的查询调用。因此,我编写了以下代码:
let ajaxObject = {
type: "POST"
,headers: {
'Accept-Encoding' : 'application/json; charset=UTF-8'
,'Content-Type' : 'application/json; charset=UTF-8'
,'SC_TRACE_ID' : UUID.UUID()
}
,url: "/proxy/report/getEnvironment"
,async : false
,data: ""
,success: function(data) {
this.status="SUCCESS";
this.dataReturned = data;
console.log('@@WOODSMAN success reached');
}
,error: function(jqXHR, textStatus, errorThrown) {
this.status="FAILURE";
this.jqXHR = jqXHR;
this.textStatus = textStatus;
this.errorThrown = errorThrown;
console.log('@@WOODSMAN failure reached');
console.log('Error on call to getEnvironment. '+textStatus+' '+errorThrown);
}
,status: "NOT_RUN"
,dataReturned : null
,jqXHR: {}
,textStatus: {}
,errorThrown: {}
};
$.ajax(ajaxObject);
console.log('@@@WOODSMAN after ajax service call' + JSON.stringify(ajaxObject));
当我运行这个时,我得到了状态为“NOT_run”的“@@@WOODSMAN after ajax服务调用”;这意味着在调用时,它既没有执行成功函数,也没有执行失败函数。请注意,请求具有async:false,set,因此它没有理由执行异步调用
可以用Javascript进行套接字编程吗?很明显,进行同步调用变得异常困难。您应该知道JS是异步的,意味着任何处理WEB API的代码, 它不会等待它完成,而是会继续执行下一行代码 在您共享的代码段中
let appConfig = http.post("/proxy/report/getEnvironment", "",httpOptions)
.toPromise().then(data => {
this.setConstants(data);
});
是异步的。因此JS引擎不会等待它完成,它将执行下一行代码。即:
if(this.constants == null) {
console.log('@@@WOODSMAN appConfig is null even after service call');
}
由于上述行是在服务调用完成之前执行的,因此
this.constants
此时为null
。这就是您能够在控制台中看到最后一条语句的原因
要检查this.constants
是否为null
,即使在服务调用之后,也可以按如下方式修改代码:
let appConfig = http.post("/proxy/report/getEnvironment", "",httpOptions)
.toPromise().then(data => {
this.setConstants(data);
if(this.constants == null) {
console.log('@@@WOODSMAN appConfig is null even after service call');
}
});
**更新:
这是实现async wait
的方法:
public async loadAppConfig() {
let http = this.injector.get(HttpClient);
let appConfig = await http.post("url",{options})
.toPromise().then(data => {
.... next lines
});
console.log('this line will not execute until await is finished');
}
这是stackblitz演示: 你是如何调用这个服务的?这是一篇帖子,除此之外,我不知道库是如何实现的。我看到了Javascript在同步/异步方面的不同表现。关于堆栈溢出,我在前面看到了一个这样的链接:。媒体上的另一个人声称,使用toPromise()将可观察到的内容转换为承诺,然后强制它等待完成。其中只有一半似乎是正确的。上面的“如果”测试只是为了证明一点。我需要一些东西,任何东西,可以让我把我所做的事情建立在从服务中获得的价值的基础上。那么你有什么疑问呢?不要不必要地使事情复杂化。无论是可观察的还是承诺的,它们都用于处理异步调用。它们都不会改变JS的行为方式。如果希望在异步调用完成后检查结果,则必须检查内部回调。每个方法都有自己的回调处理机制。我的理解是,您希望逐行串行执行代码。您可以通过实现async-await轻松做到这一点。也许您没有看到它,但我将其包装到了一个异步函数中,但它仍然没有侦听并使其异步。我没有看到您使用
aync await
的任何地方。更新了我的回答谢谢@programoholic。我不确定我和你做的有什么不同,但我现在要等待。我可以把这个盒子装满谢谢。