Javascript 如何仅在完成时从递归函数返回对象?

Javascript 如何仅在完成时从递归函数返回对象?,javascript,typescript,react-native,Javascript,Typescript,React Native,我调用一个递归函数返回一个对象,该对象在每次迭代中都被返回 async fetchRecipe(recipe: any) { console.log("fetchRecipe"); // Start with a root recipe let rootRecipe: Recipe = { id: recipe.id, name: recipe.name, ingredients: [], childRecipes: [

我调用一个递归函数返回一个对象,该对象在每次迭代中都被返回

  async fetchRecipe(recipe: any) {
    console.log("fetchRecipe");
    // Start with a root recipe
    let rootRecipe: Recipe = {
      id: recipe.id,
      name: recipe.name,
      ingredients: [],
      childRecipes: []
    }
    // Kick off recursive function
    let result = await this.recursivelyBuildRecipe(rootRecipe);
    console.log("Fetch Recipe returned");
    return result
  }

  async recursivelyBuildRecipe(recipe: Recipe) {
    // fetches using the API
    console.log("recursivelyBuildRecipe");
    this.fetchChildren('http:///recipes/get_children', 'id=' + recipe.id)
      .then(async x => {
        await x.data.children.forEach((async(child: { type: any; ItemId: string; name: string; }) => {
          switch (child.type) {
            case 'ingredient':
              // if ingredient
              let ingredient: Ingredient = {
                id: child.ItemId,
                name: child.name,
                unit: 1
              }
              this.allIngredients.push(ingredient);
              recipe.ingredients.push(ingredient);
              break
            case 'recipe':
              let subRecipe: Recipe = {
                id: child.ItemId,
                name: child.name,
                ingredients: [],
                childRecipes: []
              }
              await this.recursivelyBuildRecipe(subRecipe)
              recipe.childRecipes.push(subRecipe)
              break
          }
        }))
      })
    // This is returning the same amount of times the recursive function is called, I want it to only return once complete.
    var obj = { "recipes": recipe, "ingredients": this.allIngredients }
    return await obj;
我只希望在递归操作完成后返回一个对象。而不是每次迭代

  async fetchRecipe(recipe: any) {
    console.log("fetchRecipe");
    // Start with a root recipe
    let rootRecipe: Recipe = {
      id: recipe.id,
      name: recipe.name,
      ingredients: [],
      childRecipes: []
    }
    // Kick off recursive function
    let result = await this.recursivelyBuildRecipe(rootRecipe);
    console.log("Fetch Recipe returned");
    return result
  }

  async recursivelyBuildRecipe(recipe: Recipe) {
    // fetches using the API
    console.log("recursivelyBuildRecipe");
    this.fetchChildren('http:///recipes/get_children', 'id=' + recipe.id)
      .then(async x => {
        await x.data.children.forEach((async(child: { type: any; ItemId: string; name: string; }) => {
          switch (child.type) {
            case 'ingredient':
              // if ingredient
              let ingredient: Ingredient = {
                id: child.ItemId,
                name: child.name,
                unit: 1
              }
              this.allIngredients.push(ingredient);
              recipe.ingredients.push(ingredient);
              break
            case 'recipe':
              let subRecipe: Recipe = {
                id: child.ItemId,
                name: child.name,
                ingredients: [],
                childRecipes: []
              }
              await this.recursivelyBuildRecipe(subRecipe)
              recipe.childRecipes.push(subRecipe)
              break
          }
        }))
      })
    // This is returning the same amount of times the recursive function is called, I want it to only return once complete.
    var obj = { "recipes": recipe, "ingredients": this.allIngredients }
    return await obj;

我不确定我是否了解这里的具体情况,但一般来说,您可以做的是:

  • this.fetchChildren
    添加
    wait
    (否则,您似乎因为突变而没有及时获得结果)
  • 将第二个布尔参数添加到递归函数(即
    isMainCall
    ),仅第一次传递它(当您开始递归时),并在最后将返回值添加到
    if(isMainCall)return obj
  • 不要混合使用承诺和异步/等待语法。从技术上讲,这并没有什么不正确的地方,但它令人非常困惑
  • 您需要迭代检索到的每个子项并等待它们。在我看来,最简单的方法是减少。虽然这会导致子对象的连续检索,但它在最后返回单个对象,并且更容易推理。如果速度不够快,你可以用Promise.all做得更好,然后自己合并结果
  • 我不确定上述语法是否100%正确,但您应该能够理解:

  • 您正在等待一个对象。这与
    returnpromise.resolve({“recipes”:…})相同