我有一个链接两个API调用的页面,在执行myWebView.delegate = self
函数之前将数据加载到first_data
和second_data
(这是几kb的数据操作和d3.js) :
createPage
问题在于,操纵<script src="createPage.js"></script>
<script>
var first_data, second_data = [], [];
function getFirstData(){
return new Promise(function(resolve) {
var xhr = new XMLHttpRequest();
var url = "/API/my-request?format=json"
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
first_data = JSON.parse(xhr.responseText);
resolve('1');
}
}
xhr.open("GET", url, true);
xhr.send();
});
} //similar function for getSecondData()
getFirstData()
.then(getSecondData)
.then(createPage(first_data, second_data));
</script>
中数据的某些代码显示错误,例如“createPage
”。在那个特定错误的情况下,这是因为我尝试对应该从API请求加载的一些数据执行can't convert undefined to object
。一些观察:
Object.keys(data[0])
,那么页面绘制,但所有图形表明它们没有数据填充。< / LI>
can't convert undefined
的开头和结尾插入了console.log("starting")
语句。在加载时查看网络和js控制台输出,createPage()
输出发生在网络活动中显示两个API GET请求之前。这是真正发生的事情的代表(即你可以混合javascript控制台和网络控制台时间吗?)因此,显然我无法在需要时访问数据。
starting
不正确吗?答案 0 :(得分:1)
Promise.prototype.then()
期望2个参数(onFulfilled & onRejected
)为function-expression(OR handler or callback)
,因为它是一个函数(处理程序),当 Promise完成时将调用它
在您的情况下,createPage(first_data, second_data)
将在解释器解释语句时调用函数createPage
。
使用anonymous function
作为参数并在其中调用您的函数。
getFirstData()
.then(getSecondData)
.then(function() {
createPage(first_data, second_data);
});
编辑:如果您没有专门向回调传递任何参数,可以使用.then(FUNCTION_NAME)
答案 1 :(得分:1)
在函数式编程和使用promises中,你应该将getFirstData(和getSecondData)重构为以下形式:
function getFirstData(){
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
var url = "/API/my-request?format=json"
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
// Resolve the result, don't assign it elsewhere
resolve(JSON.parse(xhr.responseText));
} else {
// Add rejection state, don't keep the promise waiting
reject("XHR Error, status = ", xhr.status);
}
}
xhr.open("GET", url, true);
xhr.send();
});
}
然后解决这样的承诺(假设第一个和第二个数据不相互依赖)
Promise.all([getFirstData(), getSecondData()]).then(function(allData){
var first_data = allData[0];
var second_data= allData[1];
return createPage(first_data, second_data);
}).catch(function(error){
console.log("Error caught: ", error);
});
为了使事情更清晰,您可以从以下位置更改createPages:
function createPage(first_data, second_data){
// Function body
}
到
function createPage(data){
var first_data = data[0];
var second_data= data[1];
// Function body
}
和Promise部分:
Promise.all([getFirstData(), getSecondData()]).then(createPage);
注意它变得多么短暂?