Javascript 为什么我似乎需要承诺和回调来向全局变量公开JSON数据?
据我所知,要将获取的JSON数据公开给全局变量,我需要使用promise或回调函数。我的代码正在运行,但它同时使用了 我正在使用jQuery的Javascript 为什么我似乎需要承诺和回调来向全局变量公开JSON数据?,javascript,json,ajax,callback,promise,Javascript,Json,Ajax,Callback,Promise,据我所知,要将获取的JSON数据公开给全局变量,我需要使用promise或回调函数。我的代码正在运行,但它同时使用了 我正在使用jQuery的.done创建一个承诺,我想在.done中实例化我的nowNext()函数。.done中的代码不应该只在承诺(即JSON数据)返回后执行吗 如果我在此时调用nowNext()并记录我的timeObj它是一个空对象,但是如果我在中实例化timeCall()回调函数,那么它就会实例化nowNext()我的timeObj获取JSON数据 // define th
.done
创建一个承诺,我想在.done
中实例化我的nowNext()
函数。.done
中的代码不应该只在承诺(即JSON数据)返回后执行吗
如果我在此时调用nowNext()
并记录我的timeObj
它是一个空对象,但是如果我在中实例化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
回调实际返回所需的数据子集(尽管仍封装在承诺中),然后通过调用nowNext
。然后,可以确保数据自动沿着承诺链传递
还请注意,错误处理也通过承诺链完成-如果nowTime
函数返回被拒绝的承诺(或引发异常),则以下。然后将自动跳过调用,代码将落入失败处理程序。应避免全局变量。当您开始进行异步调用时,您需要确保以下所有代码都是通过回调/承诺链进行的,如果可能的话,将变量作为参数传递
我的首选解决方案是:
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
回调实际返回所需的数据子集(尽管仍封装在承诺中),然后通过调用nowNext
。然后,可以确保数据自动沿着承诺链传递
还请注意,错误处理也通过承诺链完成-如果nowTime
函数返回被拒绝的承诺(或引发异常),则以下。然后
调用将自动跳过,代码将落入。fail
处理程序。我不明白您在问什么。我觉得你的代码很好。解析承诺时调用传递给.done()
的函数,收到getJSON()
响应时会调用该函数。在该回调中,您(间接地)调用nowNext()
,因此全局变量将被初始化。到底有什么是不清楚的?你使用了多少功能取决于你自己。您可以将console.log(timeObj)
调用直接放在timeCall
中,甚至可以放在done
中。这不会有什么区别。@AlanSutherland你完全没有理由不知道-要知道console.log
有时会做一些奇怪的事情传递值是一个参数:nowNext(data.program[i])
带有function nowNext(data){console.log(data)}
。更好的是,有.done()
doreturn timeObj
然后执行。然后(现在下一步)
在承诺链中自动传递对象的点我不明白你在问什么。我觉得你的代码很好。解析承诺时调用传递给.done()
的函数,收到getJSON()
响应时会调用该函数。在该回调中,您(间接地)调用nowNext()
,因此全局变量将被初始化。到底有什么是不清楚的?你使用了多少功能取决于你自己。您可以将console.log(timeObj)
调用直接放在timeCall
中,甚至可以放在done
中。这不会有什么区别。@AlanSutherland你完全没有理由不知道-要知道console.log
有时会做一些奇怪的事情传递值是一个参数:nowNext(data.program[i])
带有function nowNext(data){console.log(data)}
。更好的是,有.done()
doreturn timeObj
然后执行。然后(nowNext)
在承诺链中,在该点自动传递对象