2017-09-08 141 views
0

我對承諾的回報有一些問題。之前,HTTP調用過程中,我用這樣的函數返回一個承諾:在函數中包裝兩個承諾

get_data: function (url) 
{ 
    let timestamp = new Date(); 
    return $http({ 
     method: "GET", 
     url: url 
     headers: { 
       'timestamp': timestamp, 
     } 
    }).then(
      function successCallback(response) 
      { 

       console.dir("Response:"); 
       console.dir(response["data"]); 

       return (response["data"]) 
      }, 
      function errorCallback(response) 
      { 
       console.dir(response); 
       return response; 
      }); 
    }, 

這是很簡單的,我可以這樣使用它:

get_data('my_awesome_url').then(function(response){ 
    let my_awesome_data = response 
}) 

罪魁禍首是時間戳啄。我使用它來進行認證,爲什麼不重要,但通過從客戶端獲得它,我常常是以另一種語言設置的不合時宜的系統或系統的受害者。

我的解決方案是創建一個請求服務器時間戳的函數。但通過這樣做,我必須首先等待時間戳請求,然後啓動另一個請求並等待它結束。 這是我不知道該怎麼做的地方。我的代碼是這樣的:

get_data: function (url) 
{ 
    let timestamp = new Date(); 
    get_timestamp().then(function(){ 
     return $http({ 
      method: "GET", 
      url: url 
      headers: { 
        'timestamp': timestamp, 
      } 
     }).then(
       function successCallback(response) 
       { 

        console.dir("Response:"); 
        console.dir(response["data"]); 

        return (response["data"]) 
       }, 
       function errorCallback(response) 
       { 
        console.dir(response); 
        return response; 
       }); 
     }); 
    }, 

但我不知道我應該返回什麼。我是否應該返回get_timestamp承諾並在「然後」等待另一個請求結束?我應該讓get_timestamp進行同步調用,因爲畢竟它只是一個小日期字符串? 我在我的代碼中一直使用舊函數,所以只保留舊的使用方法(只有一個),會很棒。

一如既往地感謝所有。

+1

'回報get_timestamp()。然後(函數(){...' – dfsq

回答

1

你會寫這樣的說法:

get_data: function(url) { 
    return get_timestamp() // request the timestamp this returns a promise 
    .then(function(timestamp) { // on which then is called wich itself returns a promise. 
         // the callback of this then is called as soon 
         // as the promise returned by timestamp 
         // is resolved 
     return $http({ 
     method: "GET", 
     url: url 
     headers: { 
      'timestamp': timestamp, 
     } 
     }) // here you return the Promise that is created by the $http 
    }) 
    .then(function(response) { // the callback of this then is called as soon 
           // as the previous promise was resolved 

     console.dir("Response:"); 
     console.dir(response["data"]); 

     return (response["data"]) 
    }) 
    .catch(function(response) { 
     console.dir(response); 
     return response; 
    }); 
}, 

首先我會用:

.then(function(response) { 
    console.dir("Response:"); 
    console.dir(response["data"]); 

    return (response["data"]) 
}) 
.catch(function(response) { 
    console.dir(response); 
    return response; 
}); 

而不是

.then(
    function successCallback(response) { 

    console.dir("Response:"); 
    console.dir(response["data"]); 

    return (response["data"]) 
    }, 
    function errorCallback(response) { 
    console.dir(response); 
    return response; 
    }); 
}) 

因爲它更容易稍後閱讀,如果你有更長的鏈條。

return返回是通過鏈創建的最後一個承諾,這是由呼叫.catch(function(response) {...}

+0

@ T-尼澤命名功能是大家一個好東西,更容易理解調用堆棧,如果錯誤被拋出。如果OP是確定(稍後更詳細的代碼,你不應該勸阻它) – skylize

+0

@skylize它是關於命名函數,然後關於'.then(成功,錯誤)'vs'.then(回調).catch(回調)'' .catch'使得後面更容易找到'.catch'語句,通過'.then(成功,錯誤)'這些錯誤回調並不容易看到/發現.OP捕獲錯誤,所以這不會出現在任何錯誤堆棧中,所以在這種特殊情況下,命名函數不太可能有好處。 –

+0

除了明顯的語法外,.catch和.then(成功,錯誤)的工作方式相同嗎? –

1

返回一個你應該鏈的承諾並返回鏈的結果:

function get_data(url) { 
    return get_timestamp() 
    .then((timestamp) => { 
     return $http({ 
     method: "GET", 
     url: url, 
     headers: { 
      timestamp: timestamp 
     } 
     }); 
    }) 
    .then((response) => { 
     console.dir("Response:"); 
     console.dir(response["data"]); 

     return response["data"]; 
    }) 
    .catch((response) => { 
     console.dir(response); 
     return response; 
    }); 
} 

請注意,我們在鏈的末尾只需要一個.catch即可捕獲所有異常。