ES6 fetch 调用中链接 .then 函数

zad*_*ees 0 javascript promise ecmascript-6 fetch-api

我一直在寻找一种方法来解决这个问题,如果我的搜索技能达不到标准,我深表歉意。

我的问题:我正在获取 API,我想知道所有数据何时已完全加载。通读文档,我似乎可以将 .then 语句与 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()  
}
Run Code Online (Sandbox Code Playgroud)

如果是异步的,那就太好了,但这些事件需要同步,因为我正在尝试处理由先前调用 showSearchResults() 创建的内容;

任何帮助深表感谢。

小智 5

链接 a.then并不能保证代码会按顺序执行,除非您从前一个.then调用中返回了一个 Promise。在您的示例中,如果您希望第二个console.log在之后执行showSearchResults,您应该return showSearchResults()将其链接起来.then(这仅在showSearchResults返回承诺时有效;如果没有,您将需要将其包装在类似于 for 的方式中fetchStatus) 。

类似地,如果你想将 a 链接.then到 a 上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!
Run Code Online (Sandbox Code Playgroud)