Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么我似乎需要承诺和回调来向全局变量公开JSON数据?_Javascript_Json_Ajax_Callback_Promise - Fatal编程技术网

Javascript 为什么我似乎需要承诺和回调来向全局变量公开JSON数据?

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

据我所知,要将获取的JSON数据公开给全局变量,我需要使用promise或回调函数。我的代码正在运行,但它同时使用了

我正在使用jQuery的
.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()
do
return timeObj
然后执行
。然后(现在下一步)
在承诺链中自动传递对象的点我不明白你在问什么。我觉得你的代码很好。解析承诺时调用传递给
.done()
的函数,收到
getJSON()
响应时会调用该函数。在该回调中,您(间接地)调用
nowNext()
,因此全局变量将被初始化。到底有什么是不清楚的?你使用了多少功能取决于你自己。您可以将
console.log(timeObj)
调用直接放在
timeCall
中,甚至可以放在
done
中。这不会有什么区别。@AlanSutherland你完全没有理由不知道-要知道
console.log
有时会做一些奇怪的事情传递值是一个参数:
nowNext(data.program[i])
带有
function nowNext(data){console.log(data)}
。更好的是,有
.done()
do
return timeObj
然后执行
。然后(nowNext)
在承诺链中,在该点自动传递对象