我开始研究Android应用程序。我现在需要使用API来获取一些信息。我正在使用电影API,因此它包含ID,标题和其他一些信息。我的问题是,在这个URL我没有我需要的每一个信息所以我必须为每部电影另外获取获取额外的信息但是我注意到第一次JS在第一次获取中运行代码(没有嵌套的提取)然后它运行嵌套的提取。这样一些信息不会显示在屏幕上。
fetch(movie)
.then(function(response) { return response.json(); })
.then(function(responseObject) {
movies.value = responseObject;
for(var i=0;i<movies.value.results.length;i++)
{
movies.value.results[i].poster_path = poster+movies.value.results[i].poster_path;
var info = "http://api.themoviedb.org/3/movie/"+movies.value.results[i].id+"?api_key";
fetch(info)
.then(function(response) { return response.json(); })
.then(function(responseObject) {
moreInfo.value = responseObject;
if(j < movies.value.results.length)
{
movies.value.results[j].runtime = moreInfo.value.runtime;
console.log("print 1 "+movies.value.results[j]);
j++;
}
});
console.log("print 2 "+movies.value.results);
}
});
我在这里尝试做的是从第二次获取运行时添加到我的电影Observable对象。结果的分类版本:
print 2:movies.value.results
print 1:movies.value.results [i]
我所说的问题是第一次获取中的代码是在不执行嵌套提取的情况下执行的,然后执行嵌套的提取。对不起,如果我做了一些非常糟糕的事情,但我刚开始开发android,请告诉我怜悯:D
*很抱歉没有解释我的j变量。它被定义为取消(电影)之上的零。我使用它的唯一原因是因为我在fetch(info)中总是处于我可以从movie.value.results.length获取的最大数量,因为我需要在特定的movie.value.result [j]传递运行时。所以我有一个只有在执行fetch(info)时才会增加的计数器。
答案 0 :(得分:2)
这个片段也可能有一些其他问题,如评论中指出的那样,但我想我知道主要的困惑在哪里来了。
我说的问题是第一次获取中的代码是在不执行嵌套提取的情况下执行的,然后执行嵌套提取。
事实并非如此。或者,至少控制台日志的顺序并不意味着这一点。外部then-callback内执行的顺序是
fetch(info)
此语句开始提取数据.then(function(response){ ... })
注册一个回调,以便在承诺得到解决时执行。请注意,由于提取是异步,因此回调函数会立即调用而不是。当数据加载完成后,它将在稍后调用。同时,调用堆栈的同步执行仍在继续。.then(function(responseObject) { ... })
这里也是一样的。我们创建了一个在数据就绪时运行的函数(如果有的话)。同时, 之外的语句仍然可以评估该函数。console.log("print 2 "+movies.value.results);
现在出现第一个日志语句。 JavaScript执行不会停止等待提取完成。这就是异步编程的全部概念。现在,一些时间过去了,最后,数据已经完成加载。
return response.json();
fetch
返回的Promise获得了 ,因为操作成功了。然后它运行您之前提供的回调。moreInfo.value = responseObject;
if(j < movies.value.results.length)
{
movies.value.results[j].runtime = moreInfo.value.runtime;
console.log("print 1 "+movies.value.results[j]);
j++;
}
这是我们创建的第二个回调,同样适用于此处。现在数据已经准备就绪,可以执行。我不确定整个j
的事情,但显然执行最终会转到console.log("print 1 "+movies.value.results[j]);
声明。这里要理解的重要一点是,'print 1'语句是否在'print 2'行上方的源代码中是无关紧要的。 “打印1”安排在稍后,即第二次提取完成时。
修正版
var info = //URL
fetch(info)
.then(function(response) { return response.json(); })
.then(function(responseObject) {
moreInfo.value = responseObject;
...
console.log("print 1 "+movies.value.results[j]);
...
})
.then(function(){
console.log("print 2 "+movies.value.results);
});
现在也可能是我完全误解了这个问题。但如果这是关于异步性的,您还应该查看上面链接的MDN Promise文档和this SO question about asynchronicity in Node.js,这也适用于其他JavaScript环境。