我开始开发 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 对象中。结果的排序版本:
打印2:电影.value.结果
打印 1:movie.value.results[i]
正如我所说,问题是执行第一个 fetch 内的代码时没有执行嵌套的 fetch,然后执行嵌套的 fetch。抱歉,如果我做了一些很糟糕的事情,但我刚刚开始在 Android 上开发,所以请怜悯我:D
*抱歉没有解释我的 j 变量。它在 fetch(movie) 之上被定义为零。我使用它的唯一原因是因为我在 fetch(info) 中始终处于我可以从 movie.value.results.length 获取的最大数量,并且因为我需要在特定的 movie.value.result[j] 处传递运行时。所以我有一个计数器,仅在执行 fetch(info) 时才会增加。
最佳答案
这个片段可能还有其他一些问题,就像评论中指出的那样,但我想我知道主要的困惑来自哪里。
The problem as i said is that the code inside the first fetch is executed without executing the nested fetch and then the nested fetch executes.
这不是真的。或者,至少控制台日志的顺序并不意味着这一点。外部then回调内部的执行顺序是
-
fetch(info)
该语句开始获取数据 -
.then(function(response){ ... })
注册一个回调,以便在 Promise 得到解决时执行。请注意,由于获取是异步,因此回调函数不会立即被调用。当数据加载完成后,它将被调用。同时,调用堆栈的同步执行继续进行。 -
.then(function(responseObject) { ... })
这里同样的事情。我们创建一个函数,在数据准备好(如果有的话)时运行。同时,该函数外部的语句仍然可以被评估。 -
console.log("print 2 "+movies.value.results);
现在是第一个日志语句。 JavaScript 执行不会停止以等待获取完成。这就是异步编程的全部思想。
现在,过了一段时间,数据终于加载完毕。
-
return response.json();
Promise从fetch
返回因为操作成功而满足。然后它会运行您之前提供的回调。 -
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 环境。
关于JavaScript 嵌套获取 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37031839/