[英]Console.log returns what I need but return returns an '[object Promise]' string
我有兩個 JSON。 一個來自變量,一個來自 API 調用,基於它們我正在嘗試生成 HTML 代碼。 我正在使用遞歸 function 因為 JSON 可以包含嵌套部分。 那些 JSON 還可能包含幾個“選擇”,這些“選擇”應該具有基於另一個 API 調用(“源”)的“選項”。 當我嘗試執行代碼時,一切正常,但是 function 返回 [object Promise] 而不是“選項”,而在控制台中有正確的值。
這是變量的示例(API 響應類似):
var constructor = {
"element" : {
"data" : [
{
"type" : "section",
"id" : "id1",
"elements" : [
{
"type" : "input",
"subtype" : "text",
"label" : "Address",
"id" : "address",
},
{
"type" : "section",
"id" : "id2",
"elements" : [
{
"type" : "h3",
"text" : "Some text"
},
{
"type" : "select",
"label" : "Klient",
"id" : "id3",
"width" : 100,
"elements" : "source",
"source" : "source_path"
}
]
},
{
"type" : "section",
"id" : "id4",
"elements" : [
{
"type" : "h3",
"text" : "Some text 2"
}
]
}
]
}
]
}
}
這是代碼:
async function getData(url = '') {
const response = await fetch(url, {
method: 'GET',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json'
}
});
return response.json();
}
const generateElements = (obj) => {
if(obj.type == 'input') doSomething();
if(obj.type == 'h3') doSomething();
if(obj.type == 'select'){
return `<select id="${obj.id}">
${
typeof obj.elements == 'object' ?
Array.isArray(obj.elements) &&
obj.elements.map((element) => {
return `<option id="${element}">${element}</option>`
}).join("")
: obj.elements == 'source' &&
getData(obj.source)
.then(data => {
data.map((element) => {
console.log(element.id, element.name)
return `<option id="${element.id}">
${element.name}
</option>`
}).join('')
})
}
</select>
<label for="${obj.id}">${obj.label}</label></div>`
}
if(obj.type == 'section'){
return `<section id="${obj.id}">
${ obj.hasOwnProperty('elements') &&
obj.elements.map((element) => {
return generateElements(element)
}).join('')
}
</section>`
}
}
getData('the_url2')
.then(data => {
data.map((element) => {
element.elementToAppend &&
jQuery(element.elementToAppend).append(generateElements(JSON.parse(element.data)))
})
});
constructor.map((element) => {
jQuery(element.elementToAppend).append(generateElements(JSON.parse(element.data)))
})
我嘗試將 generateElements function 更改為異步,但隨后代碼生成 [object Promise] 代替部分。 我的另一個想法是等待 API 調用,但隨后出現“等待僅在異步函數中有效”錯誤。 When I assign the API call from select to const and then return the value it generates proper html code in the console, but still [object Promise] in the result of the function. 我也嘗試了許多其他解決方案,但沒有成功。
我不知道如何繼續,但我無法更改 API 響應。 我在使用框架和庫方面受到 Qualtrics 的限制。
編輯:感謝@Bergi 的支持,我能夠解決我的問題。 所以:
我對 generateElements 使用了異步:
const generateElements = async (obj) => { ... }
等待獲取 function:
await getData(obj.source)
.then(data => {
data.map((element) => {
console.log(element.id, element.name)
return `<option id="${element.id}">
${element.name}
</option>`
}).join('')
})
和 Promise 用於遞歸:
( await Promise.all(obj.elements.map(async (element) => {
return await generateElements(element)
})
) ).join('')
再次感謝@Bergi::)
如果您嘗試獲取 API 響應數據而不是 promise,您可能需要await
response.json()
。
async function getData(url = '') {
const response = await fetch(url, { /* ... */ });
// return response.json();
return await response.json();
}
正如@bergi 指出的那樣,您的generateElements
function 也需要是異步的。
typeof obj.elements == 'object' ?
Array.isArray(obj.elements) &&
obj.elements.map((element) => {
return `<option id="${element}">${element}</option>`
}).join("")
: obj.elements == 'source' &&
(await getData(obj.source)) // ** await here
.map((element) => {
console.log(element.id, element.name)
return `<option id="${element.id}">
${element.name}
</option>`
})
.join('')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.