Node.js调用FoodData Central API时console.log输出顺序问题
控制台输出顺序不符合预期问题
问题描述
调用FoodData Central API获取食品营养数据时,期望控制台先打印Protein:、Fats:、Carbs:,紧接着输出对应营养数值,但实际输出是所有字符串先打印完成,才输出数值:
Protein: Fats: Carbs: 8.8 0 26.2
原代码
const fetch = require("node-fetch"); const params = { api_key: '<api_key>', query: 'chicken breast raw', dataType: ["Survey (FNDDS)"], pagesize: 5, } const api_url = `https://api.nal.usda.gov/fdc/v1/foods/search?api_key=${encodeURIComponent(params.api_key)}&query=${encodeURIComponent(params.query)}&dataType=${encodeURIComponent(params.dataType)}&pageSize=${encodeURIComponent(params.pagesize)}` function getData(){ return fetch(api_url).then(response => response.json()) } console.log("Protein:") getData().then(data=> console.log(data.foods[0].foodNutrients[0].value)) console.log("Fats:") getData().then(data=> console.log(data.foods[0].foodNutrients[1].value)) console.log("Carbs:") getData().then(data=> console.log(data.foods[0].foodNutrients[2].value))
问题原因
fetch是异步操作,会在后台发送请求,而console.log是同步代码,会立即执行。因此所有字符串打印语句会先全部执行完毕,等API请求返回后,才会执行then回调里的数值打印。另外原代码重复调用3次API,造成不必要的资源浪费。
解决方案
方案1:使用async/await(推荐)
通过async/await让异步代码逻辑更直观,同时只发起一次API请求,拿到数据后依次打印:
const fetch = require("node-fetch"); const params = { api_key: '<api_key>', query: 'chicken breast raw', dataType: ["Survey (FNDDS)"], pagesize: 5, } const api_url = `https://api.nal.usda.gov/fdc/v1/foods/search?api_key=${encodeURIComponent(params.api_key)}&query=${encodeURIComponent(params.query)}&dataType=${encodeURIComponent(params.dataType)}&pageSize=${encodeURIComponent(params.pagesize)}` async function getNutritionData() { const response = await fetch(api_url); const data = await response.json(); const nutrients = data.foods[0].foodNutrients; console.log(`Protein: ${nutrients[0].value}`); console.log(`Fats: ${nutrients[1].value}`); console.log(`Carbs: ${nutrients[2].value}`); } getNutritionData();
方案2:单次请求后统一打印
如果不想用async/await,可以在一次API请求的then回调里完成所有打印操作:
const fetch = require("node-fetch"); const params = { api_key: '<api_key>', query: 'chicken breast raw', dataType: ["Survey (FNDDS)"], pagesize: 5, } const api_url = `https://api.nal.usda.gov/fdc/v1/foods/search?api_key=${encodeURIComponent(params.api_key)}&query=${encodeURIComponent(params.query)}&dataType=${encodeURIComponent(params.dataType)}&pageSize=${encodeURIComponent(params.pagesize)}` function getData(){ return fetch(api_url).then(response => response.json()) } getData().then(data => { const nutrients = data.foods[0].foodNutrients; console.log(`Protein: ${nutrients[0].value}`); console.log(`Fats: ${nutrients[1].value}`); console.log(`Carbs: ${nutrients[2].value}`); });
预期输出效果
执行后会得到符合需求的输出:
Protein: 8.8 Fats: 0 Carbs: 26.2
内容的提问来源于stack exchange,提问作者Florian Dima
相关产品推荐
相关产品推荐

