Javascript Angular:.then()块在我的异步函数之前执行
我试图在RecipesComponent构造函数中填充recipeList,但在异步GetRecipesService.getRecipes()完成之前,正在执行then()块Javascript Angular:.then()块在我的异步函数之前执行,javascript,node.js,angular,typescript,web,Javascript,Node.js,Angular,Typescript,Web,我试图在RecipesComponent构造函数中填充recipeList,但在异步GetRecipesService.getRecipes()完成之前,正在执行then()块 export class RecipesComponent{ constructor(getRecipesService: GetRecipesService){ getRecipesService.getRecipes().then(promise=>{ this.
export class RecipesComponent{
constructor(getRecipesService: GetRecipesService){
getRecipesService.getRecipes().then(promise=>{
this.recipeList = getRecipesService.recipes;
console.log("RecipesComponent recipeList: "+this.recipeList);
});
}
recipeList = [];
}
@NgModule()
export class GetRecipesService{
recipes: any[];
constructor(private http:HttpClient){
this.http = http;
}
async getRecipes(){
this.http.get<any[]>('http://localhost:4200/recipes').subscribe(response=>{
this.recipes = response;
console.log("getRecipes this.recipes: "+this.recipes);
})
}
}
导出类组件{
构造函数(GetRecipeService:GetRecipeService){
getRecipesService.getRecipes()。然后(承诺=>{
this.recipeList=getRecipesService.recipes;
log(“RecipeComponent recipeList:+this.recipeList”);
});
}
recipeList=[];
}
@NgModule()
导出类getRecipes服务{
食谱:任何[];
构造函数(专用http:HttpClient){
this.http=http;
}
异步getRecipes(){
this.http.get('http://localhost:4200/recipes)。订阅(响应=>{
这个。配方=反应;
log(“getRecipes this.recipes:+this.recipes”);
})
}
}
在我的web浏览器中,我的控制台输出为:
如何让我的recipes组件等待getRecipes完成?将getRecipes方法更改为只返回一个可观察值,而不将其标记为async
getRecipes() {
return this.http.get<any[]>('http://localhost:4200/recipes');
}
在模板中,使用异步管道订阅可观察的
<ng-container *ngIf="recipeList$ | async as recipeList">
{{ recipeList | json }}
</ng-container>
{{recipeList | json}}
异步管道不符合逻辑地为您管理订阅。我不太确定w/typescript,但我认为问题在于,按照执行顺序:
getRecipesService.getRecipes()
启动getRecipes
将this.https.get
放入异步堆栈,然后返回getRecipes
已返回,getRecipes()。然后调用,然后返回
this.https.get
从异步堆栈中提取,并调用.subscribe()
async
函数可以返回一个承诺,该承诺将在继续之前等待调用解析函数:
async getRecipes(){
return new Promise ((resolve,reject)=>{
this.http.get(url).subscribe(response=>{
this.recipes = response;
resolve(); // .then fires after this
})
})
}
以添加一些额外的嵌套行为代价,此方法不会更改代码结构,但如果您愿意了解wait
:
2等待关键字
在async
函数中,您可以等待承诺,这将阻止函数在承诺兑现之前返回:
async getRecipes(){
this.recipes = await this.http.get(url).toPromise();
}
进一步阅读:感谢所有发表评论的人,我真的很爱这个社区
对于任何找到这篇文章寻找解决方案的人来说,这就是我最终的答案
@Component({
selector: 'recipes', //<recipes>
template: `<h2>List of Recipes </h2>
<li *ngFor= "let recipe of recipeList">
{{recipe.recipeName}}
</li>
`
})
export class RecipesComponent{
constructor(getRecipesService: GetRecipesService){
this.recipeList = getRecipesService.getRecipes().subscribe(promise=>{
this.recipeList = promise;
});
}
recipeList;
}
@组件({
选择器:'配方'//
模板:`食谱列表
{{recipe.recipeName}
`
})
导出类组件{
构造函数(GetRecipeService:GetRecipeService){
this.recipeList=getRecipesService.getRecipes().subscribe(承诺=>{
这个。recipeList=承诺;
});
}
互惠主义者;
}
@NgModule()
导出类getRecipes服务{
食谱:任何[];
构造函数(专用http:HttpClient){
this.http=http;
}
getRecipes(){
返回此.http.get('http://localhost:4200/recipes');
}
}
getRecipes没有返回任何内容getRecipes填充配方:任何[]您只能等待承诺,http客户端返回可观察内容。我们在Angular中不使用承诺,它是基于RxJs构建的。如果您不熟悉RxJs,那么是时候暂停您的旅程并学习RxJs了。在继续你的角度之旅之前,请确保你对观测值有一个合理的了解。@Adrianbr,非常感谢你的投入。我现在正在研究RxJs的观测值。同时,。我是否需要主要更改代码的结构以使此实现正常工作?我按照您的指示操作,在浏览器中显示的内容是:{“{u isScalar”:false,“source”:{“{u isScalar”:false,“source”:{“{u isScalar”:false,“source”:{“{u isScalar”:false},“operator”:{“concurrent”:1},“operator”:{},“operator”:}虽然这很好,也很直接,OP可能会注意到没有空间来存放this.recipes=response
,因此需要更多的重新采购…@AdrianBrand再次感谢您的回复。我的解决方案是返回您提到的可观察对象,然后订阅我的getRecieps()方法。非常感谢
@Component({
selector: 'recipes', //<recipes>
template: `<h2>List of Recipes </h2>
<li *ngFor= "let recipe of recipeList">
{{recipe.recipeName}}
</li>
`
})
export class RecipesComponent{
constructor(getRecipesService: GetRecipesService){
this.recipeList = getRecipesService.getRecipes().subscribe(promise=>{
this.recipeList = promise;
});
}
recipeList;
}
@NgModule()
export class GetRecipesService{
recipes: any[];
constructor(private http:HttpClient){
this.http = http;
}
getRecipes(){
return this.http.get<any[]>('http://localhost:4200/recipes');
}
}