我一直在寻找一种解决这个问题的方法,如果我的搜索技能达不到标准,我会道歉。
我的问题:我正在提取API,我想知道所有数据何时已完全加载。通过文档阅读,似乎我可以使用fetch链接.then语句,我认为这样可行。但是,似乎他们似乎都在同时开火而没有等待之前的事情。然后才完成。
这是我的代码:
fetch(myUrl, {
method: 'post',
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
credentials: 'include',
body: data
})
.then(fetchStatus)
.then(json)
.then(function(msg){
showSearchResults();
setTimeout(function(){ console.log("Next then should fire after this"); }, 4000);
})
.then(function(){
return console.log("The 2nd is firing!");
});
function fetchStatus(response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response)
} else {
return Promise.reject(new Error(response.statusText))
}
}
function json(response) {
return response.json()
}
如果它是异步的,这很好,但是这些事件需要是同步的,因为我正在尝试使用前一个调用showSearchResults()创建的内容;
非常感谢任何帮助。
答案 0 :(得分:1)
链接.then
并不保证代码将按顺序执行,除非您已从先前的.then
调用返回了承诺。在您的示例中,如果您希望第二个console.log
在showSearchResults
之后执行,则应return showSearchResults()
并将.then
链接起来(这仅在showSearchResults
有效返回一个promise;如果没有,你会希望将它包装成一个类似于fetchStatus
)的方式。
同样,如果您要将.then
链接到setTimeout
,您可以编写如下内容:
fetch(url, { method: 'post', etc... })
.then(fetchStatus)
.then(json)
.then(function(msg){
return new Promise(function(resolve, reject){
setTimeout(function() {
console.log("Next then fires after promise resolves");
resolve();
}, 4000)
})
})
.then(function(){
console.log("Second is firing")
})
.catch(err => console.log(error)) // always remember to catch errors!
答案 1 :(得分:-1)
你对then
函数的连续调用代表了对同一个promise的一系列回调,这是第一个。它们并不代表所有其他承诺,这就是它们执行速度如此之快的原因。您需要做的是将它们链接到回调函数中,如下所示:
fetch(myUrl, {
method: 'post',
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
credentials: 'include',
body: data
}
).then((response) => {
// fetch promise is resolved
fetchStatus(response).then((response) => {
// fetchStatus promise is resolved
json(response).then((msg) => {
// json promise is resolved
showSearchResults();
setTimeout(function(){
console.log("Next then should fire after this");
}, 4000);
// note that this log will execute before the previous one because
// `setTimeout` does not return a promise
console.log("The 2nd is firing!");
});
});
});
function fetchStatus(response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response)
} else {
return Promise.reject(new Error(response.statusText))
}
}
function json(response) {
return response.json()
}