Javascript Angular:.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.

我试图在RecipesComponent构造函数中填充recipeList,但在异步GetRecipesService.getRecipes()完成之前,正在执行then()块

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浏览器中,我的控制台输出为:

  • RecipesComponent recipeList:未定义

  • getRecipes this.recipes:[对象],..[对象]


  • 如何让我的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()。然后调用
    ,然后返回
  • https请求已完成
  • this.https.get
    从异步堆栈中提取,并调用
    .subscribe()
  • 而你想要的是1,2,4,5,3。你需要做的是让3等5。因此,您可以尝试:

    1承诺 (注意,我是一个普通的js编码员,不是一个typescript编码员bc还没有得到我的开发堆栈设置)
    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');
        }
    }