[英]Javascript - .push() multiple objects from for loop into multidimensional array
我正在運行一個函數,需要將 16 個對象推送到多維數組的i
位置。 我可以使用videoData.push(videoItem)
將所有數據推送到var = videoData
但我最終需要得到一個多維數組,其中每個嵌套數組包含 16 個對象。
//variables
videoData = [],
countries = ["GB", "ES", "PT", "VN", "ID"],
tags = ["?tags=english", "?tags=spanish", "?tags=portugues", "?tags=vietnam", "?tags=indonesia"]
//function
function runTask(){
for(var i = 0; i < countries.length; i++){
axios({
method: "get",
url: api_url + tags[i],
headers: {
"Content-Type": "application/json"
},
})
.then(function(response) {
var sixteenVideos = response.data
for(var x = 0; x < 16; x++){
var videoItem = {
"keys": {
video: "vid" + [x+1]
},
"values": {
url: sixteenVideos[x].slug,
thumb: sixteenVideos[x].image,
title: sixteenVideos[x].title,
desc: sixteenVideos[x].description
}
}
videoData[i].push([videoItem]);
}
console.log(videoData);
}).catch(function(error) {
console.log(error);
});
}
}
我希望最終...
var videoData = [[vid01, vid02....vid16], [vid01, vid02... vid16]]
For
循環是同步工作的,當在for
循環內執行異步操作時,當for
循環完成承諾時,它就會執行。 因此, i
的值將具有每個已解決承諾中最后一次循環迭代的值。
我不認為這里真的需要for
循環,創建一個函數可以更簡單,該函數接受一個標簽並返回一個解析為 16 個元素的數組的承諾,它可能如下所示:
var videoData = [];
var countries = ["GB", "ES", "PT", "VN", "ID"];
var tags = ["?tags=english", "?tags=spanish", "?tags=portugues", "?tags=vietnam", "?tags=indonesia"];
var tasks = tags.map(runTask);
Promise.all(tasks).then(result => {
console.log(result)
});
function runTask(tag) {
return axios({
method: "get",
url: api_url + tag,
headers: {
"Content-Type": "application/json"
},
}).then((response) =>
response.data
.slice(0, 16)
.map((video, index) => ({
"keys": {
video: "vid" + [index + 1]
},
"values": {
url: video.slug,
thumb: video.image,
title: video.title,
desc: video.description
}
}))
).catch(err => {
console.log(err)
})
}
您想使用與此類似的循環來構建多維數組
function runTask() {
var videoData = [];
for (var i = 0; i < 6; i++) {
var country = "Country -" + i;
var countryArray = [];
for (var x = 0; x < 16; x++) {
var videoItem = country + ", Video -" + x;
countryArray.push(videoItem);
}
videoData.push(countryArray);
}
}
您當前的代碼存在很多問題。 我將從頭開始,希望你能看到更好的方法來解決這個問題。 首先,axios 有很多底層的特性,每次取 json 時都不用關心。 從fetchJson
東西開始 -
const fetchJson = (url = "") =>
axios
( { method: "get"
, url
, headers: { "Content-Type": "application/json" }
}
)
.then(res => res.data)
現在,當我們編寫fetchVideos
,我們可以依賴fetchJson
並直接跳轉到我們需要對解析的響應執行的操作 -
const apiUrl =
"https://my.api/"
const fetchVideos = ({ country = "", tag = "" }) =>
fetchJson(apiUrl + tag)
.then(apiVideos => apiVideos.map(videoFromApi)) // convert each video
.then(videos => ({ country, videos })) // build response
fetchVideo
不依賴於不同的countries
和tags
數組, fetchVideo
采用對象輸入,例如 -
fetchVideos({ country: "GB", tag: "?tags=english" })
.then(console.log, console.error)
它將輸出一個對象,例如 -
// { country: "GB", videos: [ v1, v2, v3, ... ] }
這可以防止需要使用粗索引將值鏈接在一起。 我們通過依賴另一個函數videoFromApi
保持fetchVideos
高水平。 此函數會將 API 的視頻響應數據轉換為我們應用程序所需的形狀 -
const videoFromApi =
( { slug = ""
, image = ""
, title = ""
, description = ""
}
, id = 0
) =>
Object.assign
( { keys: { video: `vid${id + 1}` } }
, { values:
{ url: slug
, thumb: image
, title: title
, desc: description
}
}
)
現在來把這些都在一起,我們定義的數組requests
,並使用Promise.all
到fetchVideos
為每個請求。 注意,這使我們能夠准確地知道所有 API 提取何時完成,以便我們的程序可以進入下一步 -
const requests =
[ { country: "GB", tags: "?tags=english" }
, { country: "ES", tags: "?tags=spanish" }
, { country: "PT", tags: "?tags=portugues" }
, { country: "VN", tags: "?tags=vietnam" }
, { country: "ID", tags: "?tags=indonesia" }
]
Promise
.all(requests.map(fetchVideos)) // fetchVideos for each request
.then(console.log, console.error) // then log the output, or error if incurred
// [ { country: "GB", videos: [ v1, v2, v3, ... ] }
// , { country: "ES", videos: [ v1, v2, v3, ... ] }
// , { country: "PT", videos: [ v1, v2, v3, ... ] }
// , { country: "VN", videos: [ v1, v2, v3, ... ] }
// , { country: "IN", videos: [ v1, v2, v3, ... ] }
// ]
要查看功能演示,請展開下面的代碼段並運行它。 axios
已與randomVideos
一起模擬,以便我們可以模擬 API 請求 -
const apiUrl = "https://my.api/" const requests = [ { country: "GB", tags: "?tags=english" } , { country: "ES", tags: "?tags=spanish" } , { country: "PT", tags: "?tags=portugues" } , { country: "VN", tags: "?tags=vietnam" } , { country: "ID", tags: "?tags=indonesia" } ] const fetchJson = (url = "") => axios ( { method: "get" , url , headers: { "Content-Type": "application/json" } } ) .then(res => res.data) const fetchVideos = ({ country = "", tag = "" }) => fetchJson(apiUrl + tag) .then(apiVideos => apiVideos.map(videoFromApi)) .then(videos => ({ country, videos })) const videoFromApi = ( { slug = "" , image = "" , title = "" , description = "" } , id = 0 ) => Object.assign ( { keys: { video: `vid${id + 1}` } } , { values: { url: slug , thumb: image , title: title , desc: description } } ) // mocks const axios = async (req = {}) => ({ data: randomVideos(4) }) const randomVideos = (n = 0) => Array.from(Array(n), randomVideo) const randomVideo = (_, id) => ( { url: `videourl/${id}` , image: `images/v${id}.jpg` , title: `Video: ${id}` , description: `This is video ${1}.` } ) // run demo Promise .all(requests.map(fetchVideos)) .then(console.log, console.error) // [ { country: "GB", videos: [ v1, v2, v3, ... ] } // , { country: "ES", videos: [ v1, v2, v3, ... ] } // , { country: "PT", videos: [ v1, v2, v3, ... ] } // , { country: "VN", videos: [ v1, v2, v3, ... ] } // , { country: "IN", videos: [ v1, v2, v3, ... ] } // ]
好吧,你不能做這個"videoData[i].push"
因為數組上的位置不存在。 你可以使用這樣的輔助數組來解決這個問題:
videoData = []
videoDataAux = []
然后:
for(var x = 0; x < 16; x++){
var videoItem = {
"keys": {
video: "vid" + [x+1]
},
"values": {
url: sixteenVideos[x].slug,
thumb: sixteenVideos[x].image,
title: sixteenVideos[x].title,
desc: sixteenVideos[x].description
}
}
videoDataAux.push([videoItem]);
}
videoData[i]=videoDataAux
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.