我为一个小项目构建单页应用程序。我一直在尝试将API调用中的数据保存到对象中的电影数据库中。如果我在console.log对象,我可以看到它的所有属性和值。如果我在console.log中调用object.property,则返回' undefined'。这是代码:
from itertools import combinations_with_replacement as cwr
l1 = [1,2,3,4]
l2 = []
for i in range(0, 20):
for j in list(cwr(l1,i)):
if sum(j) < 20:
l2.append(j)
print l2
当我使用(() => {
"use strict"
/* Saving sections to variables
--------------------------------------------------------------*/
const movieList = document.getElementsByClassName('movie_list')[0];
const movieSingle = document.getElementsByClassName('movie_single')[0];
/* All standard filters for displaying movies
--------------------------------------------------------------*/
const allFilters = {
trending: 'movie/popular',
toplist: 'movie/top_rated',
latest: 'movie/now_playing',
upcoming: 'movie/upcoming'
};
const allData = {};
/* Initialize app - Get al standard data and save it in object
--------------------------------------------------------------*/
const app = {
init() {
getData(allFilters.trending, 'popular');
getData(allFilters.toplist, 'toplist');
getData(allFilters.latest, 'latest');
getData(allFilters.upcoming, 'upcoming');
this.startPage();
},
startPage() {
window.location.hash = "trending";
}
}
/* Function for getting data from the API
--------------------------------------------------------------*/
const getData = (filter, key) => {
const request = new XMLHttpRequest();
const apiKey = '?api_key=xxx';
const getUrl = `https://api.themoviedb.org/3/${filter}${apiKey}`;
request.open('GET', getUrl, true);
request.onload = () => {
if (request.status >= 200 && request.status < 400) {
let data = JSON.parse(request.responseText);
data.filter = key;
cleanData.init(data);
} else {
window.location.hash = 'random';
}
};
request.onerror = () => {
console.error('Error');
};
request.send();
};
/* Check if the data is list or single, and clean up
--------------------------------------------------------------*/
const cleanData = {
init(originalData) {
if (!originalData.results) {
this.single(originalData);
} else {
allData[originalData.filter] = originalData;
}
},
list(data) {
data.results.map(function(el) {
el.backdrop_path = `https://image.tmdb.org/t/p/w500/${el.backdrop_path}`;
});
let attributes = {
movie_image: {
src: function() {
return this.backdrop_path;
},
alt: function() {
return this.title;
}
},
title_url: {
href: function() {
return `#movie/${this.id}/${this.title}`;
}
}
}
showList(data.results, attributes);
},
single(data) {
data.poster_path = `https://image.tmdb.org/t/p/w500/${data.poster_path}`;
data.budget = formatCurrency(data.budget);
data.revenue = formatCurrency(data.revenue);
data.runtime = `${(data.runtime / 60).toFixed(1)} uur`;
data.imdb_id = `http://www.imdb.com/title/${data.imdb_id}`;
let attributes = {
movie_image: {
src: function() {
return this.poster_path;
},
alt: function() {
return this.title;
}
},
imdb_url: {
href: function() {
return this.imdb_id
}
},
similar_url: {
href: function() {
return `#movie/${this.id}/${this.title}/similar`
}
}
};
showSingle(data, attributes);
}
};
const showList = (cleanedData, attributes) => {
movieList.classList.remove('hidden');
movieSingle.classList.add('hidden');
Transparency.render(movieList, cleanedData, attributes);
};
const showSingle = (cleanedData, attributes) => {
movieSingle.classList.remove('hidden');
movieList.classList.add('hidden');
Transparency.render(movieSingle, cleanedData, attributes);
}
const formatCurrency = amount => {
amount = amount.toFixed(0).replace(/./g, function(c, i, a) {
return i && c !== "." && ((a.length - i) % 3 === 0) ? '.' + c : c;
});
return `€${amount},-`;
};
app.init();
console.log(allData); // Returns object with 4 properties: trending, toplist, latest & upcoming. Each property is filled with 20 results (movies with data) from the API.
console.log(allData.trending) // Returns 'undefined' (each property I've tried).
console.log(allData['trending']) // Returns 'undefined'
Object.keys(allData); // Returns an empty Array []
})();
时,我看到4个属性,所有属性都填充了API的结果。但是当我console.log(allData)
或console.log(allData.trending)
时,它会返回“未定义的”字样。在控制台中。有谁知道如何解决这个问题?
答案 0 :(得分:1)
当您拨打app.init()
时,它会触发init
并发送api呼叫以获取数据。
对获取数据的调用是异步的,这意味着它不会等待响应继续执行。所以它继续执行下一行代码,即console.logs
。目前,API调用尚未对数据做出响应,因此当您尝试访问data.property
时,由于数据尚未在此处,因此会失败。
当你执行log(data)
时,它会创建一个数据引用的日志,当引用稍后填充一个值时,它会在日志中更新。要在该实例中获取data
的值并阻止稍后更新,您可以尝试log(JSON.stringify(data))
。当你这样做时,你会得到一致的结果,你的日志都不起作用,这就是实际的行为。
要使日志正常工作,请查看A(同步)JAX请求的成功/加载回调,并从那里记录。或者,如果您稍后在allData
中构建cleanData
,请在cleanData
函数后调用日志。
因此,要回答您的问题,您的日志都不应该正常,因为它是异步调用。由于allData
使用稍后更新的引用的方式,使用console.log
获取对象的实际快照
console.log(JSON.stringify(allData))
日志记录