如何在 javascript 中 运行 .map 中的异步?
How to run an async inside .map in javascript?
我有一个数据库 select 函数,我希望它具有以下输出格式:
{
"recipe_id" : 1,
"recipe_name": "Spaghetti Bolognese",
"created_at": "2021-01-01 08:23:19.120",
"steps": [
{
"step_id": 11,
"step_number": 1,
"step_instructions": "Put a large saucepan on a medium heat",
"ingredients": []
},
{
"step_id": 12,
"step_number": 2,
"step_instructions": "Add 1 tbsp olive oil",
"ingredients": [
{ "ingredient_id": 27, "ingredient_name": "olive oil", "quantity": 0.014 }
]
},
]
}
我创建了以下数据库函数来执行步骤部分:
const getIngredientsStepById = async (step_id) =>{
const data = await db('step_ingredient_info as sii')
.join('steps', 'steps.step_id', 'sii.step_id')
.join('ingredients', 'ingredients.ingredient_id', 'sii.ingredient_id')
.where('steps.step_id', step_id)
let returnObj = data[0]? data.map(ingredient => {
return {
ingredient_id: ingredient.ingredient_id,
ingredient_name: ingredient.ingredient_name,
quantity: ingredient.quantity
}
}) : []
return returnObj
}
提供以下输出
[
{
"ingredient_id": 1,
"ingredient_name": "egg",
"quantity": "2 eggs"
},
{
"ingredient_id": 2,
"ingredient_name": "salt",
"quantity": "a pinch of salt"
}
]
我正在尝试将其与当前代码结合使用:
const getRecipeById = async recipe_id => {
let data = await db('recipes as r')
.join('steps as st', 'st.recipe_id', 'r.recipe_id')
.where('r.recipe_id', recipe_id)
.orderBy('st.step_number')
let recipeObj = {
recipe_name: data[0].recipe_name,
steps:
data[0].step_id ? data.map(step =>{
return {
step_id: step.step_id,
step_number: step.step_number,
instructions: step.step_instructions
}
}) : []
};
return recipeObj
}
哪个目前有这个输出,哪个好:
{
"recipe_name": "fried egg",
"steps": [
{
"step_id": 1,
"step_number": 1,
"instructions": "add oil and heat pan"
},
{
"step_id": 2,
"step_number": 2,
"instructions": "crack egg into pan in medium heat for 2-3 mins and sprinkle salt"
},
{
"step_id": 3,
"step_number": 3,
"instructions": "serve"
}
]
}
但是那一刻,我尝试使用异步来获取成分,以便我可以在步骤中添加一个成分数组,代码在那里停止工作,它显示在控制台中,但没有得到输出。
异步代码为:
const getRecipeById = async recipe_id => {
let data = await db('recipes as r')
.join('steps as st', 'st.recipe_id', 'r.recipe_id')
.where('r.recipe_id', recipe_id)
.orderBy('st.step_number')
let recipeObj = {
recipe_name: data[0].recipe_name,
steps:
data[0].step_id ? data.map(async step =>{
let ingredients = await getIngredientsStepById(step.step_id);
console.log(ingredients);
return {
step_id: step.step_id,
step_number: step.step_number,
instructions: step.step_instructions,
ingredients: ingredients
}
}) : []
};
return recipeObj
}
map
、forEach
、reduce
等,async
将无效。
但是查看您的代码,您可以将第二阶段更改为简单的 for of..
const getRecipeById = async recipe_id => {
let data = await db('recipes as r')
.join('steps as st', 'st.recipe_id', 'r.recipe_id')
.where('r.recipe_id', recipe_id)
.orderBy('st.step_number')
let recipeObj = {
recipe_name: data[0].recipe_name,
steps:
data[0].step_id ? data.map(step =>{
return {
step_id: step.step_id,
step_number: step.step_number,
instructions: step.step_instructions,
}
}) : []
};
for (const step of recipeObj.steps) {
step.ingredients = await getIngredientsStepById(step.step_id);
}
return recipeObj
}
我有一个数据库 select 函数,我希望它具有以下输出格式:
{
"recipe_id" : 1,
"recipe_name": "Spaghetti Bolognese",
"created_at": "2021-01-01 08:23:19.120",
"steps": [
{
"step_id": 11,
"step_number": 1,
"step_instructions": "Put a large saucepan on a medium heat",
"ingredients": []
},
{
"step_id": 12,
"step_number": 2,
"step_instructions": "Add 1 tbsp olive oil",
"ingredients": [
{ "ingredient_id": 27, "ingredient_name": "olive oil", "quantity": 0.014 }
]
},
]
}
我创建了以下数据库函数来执行步骤部分:
const getIngredientsStepById = async (step_id) =>{
const data = await db('step_ingredient_info as sii')
.join('steps', 'steps.step_id', 'sii.step_id')
.join('ingredients', 'ingredients.ingredient_id', 'sii.ingredient_id')
.where('steps.step_id', step_id)
let returnObj = data[0]? data.map(ingredient => {
return {
ingredient_id: ingredient.ingredient_id,
ingredient_name: ingredient.ingredient_name,
quantity: ingredient.quantity
}
}) : []
return returnObj
}
提供以下输出
[
{
"ingredient_id": 1,
"ingredient_name": "egg",
"quantity": "2 eggs"
},
{
"ingredient_id": 2,
"ingredient_name": "salt",
"quantity": "a pinch of salt"
}
]
我正在尝试将其与当前代码结合使用:
const getRecipeById = async recipe_id => {
let data = await db('recipes as r')
.join('steps as st', 'st.recipe_id', 'r.recipe_id')
.where('r.recipe_id', recipe_id)
.orderBy('st.step_number')
let recipeObj = {
recipe_name: data[0].recipe_name,
steps:
data[0].step_id ? data.map(step =>{
return {
step_id: step.step_id,
step_number: step.step_number,
instructions: step.step_instructions
}
}) : []
};
return recipeObj
}
哪个目前有这个输出,哪个好:
{
"recipe_name": "fried egg",
"steps": [
{
"step_id": 1,
"step_number": 1,
"instructions": "add oil and heat pan"
},
{
"step_id": 2,
"step_number": 2,
"instructions": "crack egg into pan in medium heat for 2-3 mins and sprinkle salt"
},
{
"step_id": 3,
"step_number": 3,
"instructions": "serve"
}
]
}
但是那一刻,我尝试使用异步来获取成分,以便我可以在步骤中添加一个成分数组,代码在那里停止工作,它显示在控制台中,但没有得到输出。
异步代码为:
const getRecipeById = async recipe_id => {
let data = await db('recipes as r')
.join('steps as st', 'st.recipe_id', 'r.recipe_id')
.where('r.recipe_id', recipe_id)
.orderBy('st.step_number')
let recipeObj = {
recipe_name: data[0].recipe_name,
steps:
data[0].step_id ? data.map(async step =>{
let ingredients = await getIngredientsStepById(step.step_id);
console.log(ingredients);
return {
step_id: step.step_id,
step_number: step.step_number,
instructions: step.step_instructions,
ingredients: ingredients
}
}) : []
};
return recipeObj
}
map
、forEach
、reduce
等,async
将无效。
但是查看您的代码,您可以将第二阶段更改为简单的 for of..
const getRecipeById = async recipe_id => {
let data = await db('recipes as r')
.join('steps as st', 'st.recipe_id', 'r.recipe_id')
.where('r.recipe_id', recipe_id)
.orderBy('st.step_number')
let recipeObj = {
recipe_name: data[0].recipe_name,
steps:
data[0].step_id ? data.map(step =>{
return {
step_id: step.step_id,
step_number: step.step_number,
instructions: step.step_instructions,
}
}) : []
};
for (const step of recipeObj.steps) {
step.ingredients = await getIngredientsStepById(step.step_id);
}
return recipeObj
}