为什么我似乎需要承诺和回调才能将 JSON 数据公开给全局变量?



据我了解,要将获取的 JSON 数据公开给全局变量,我需要使用承诺或回调函数。我的代码正在工作,但它同时使用两者...

我正在使用jQuery的.done创建一个承诺,我想在.done中实例化我的nowNext()函数。.done中的代码不应该只在返回承诺(即 JSON 数据)后执行吗?

如果我此时调用nowNext()并记录我的timeObj它是一个空对象,但是如果我在.done中实例化timeCall()回调函数,然后实例化nowNext()我的timeObj获取 JSON 数据。

// define the timeObj globally so the returned JSON can be stored
var timeObj = {};
// function gets JSON feed, argument specifies which object within feed to target
function nowTime(i){
$.getJSON("feed.json", function(data) {
console.log('getting JSON...')      
})
// a promise only to be executed once data has been fetched
.done(function(data) { 
// timeData is whichever JSON object targeted in argument
timeData = data.programme[i],
// Start building the timeObj with this data
timeObj = {
title:        timeData.title,
startTime:    timeData.start
}
// timeCall instantiates the nowNext function only  
// once the timeObj has all it's key/values defined
// directly calling nowNext at this point logs timeObj as an empty object...
timeCall();
})
.fail(function() {
console.log( "error" );
})
};
// instantiate nowTime to fetch data of current/now programme 
$(function(){ 
nowTime(0) 
})
// callback so that when nowNext is instantiated
// nowTime has already fetched timeObj data
function timeCall(){
nowNext();
}
function nowNext() {
console.log(timeObj)
}

正在获取的 JSON 数据的示例:

//////// feed.json ////////
{
"programme" : [
{
"title" : "Rick & Morty",
"startTime" : "19:00",
},
{
"title" : "News",
"startTime" : "19:30",
}
]
}

你应该避免全局变量。 当你开始进行异步调用时,你需要确保所有以下代码都是通过回调/承诺链发生的,如果可能的话,变量作为参数传递。

我的首选解决方案是:

function nowTime(i){   
return $.getJSON("feed.json", function(data) {  // NB: return
console.log('getting JSON...')      
}).then(function(data) { 
// timeData is whichever JSON object targeted in argument
timeData = data.programme[i],
// Start building a timeObj with this data
return {
title:        timeData.title,
startTime:    timeData.start
}
});
};
function nowNext(timeObj) {
...
}
$(function(){ 
nowTime(0).then(nowNext).fail(...); 
});

通过让.done回调实际返回您需要的数据子集(尽管仍然封装在 Promise 中),然后通过.then调用nowNext,您可以确保数据自动沿 promise 链传递。

另请注意,错误处理也是通过 Promise 链完成的 - 如果nowTime函数返回被拒绝的承诺(或抛出异常),则会自动跳过以下.then调用,代码将落入.fail处理程序。

最新更新