2016-12-11 56 views
1

我鏈接3個Ajax請求與到一個RESTful端點順序:如何syncronize的鏈接jQuery的承諾

  1. 把一些數據(返回{}和OK)
  2. 得到我只是把
  3. 數據
  4. 數據顯示

我已經建立了使用.then()承諾鏈。但是請求不會以預期的順序(1,2,3)而是(2,1)發生並且從OPTIONS請求開始。

爲什麼它們不按預期順序發生?

如何確保正確的順序?

var _id = x; 

function doReqs() { 
    putData(_id, data) 
    .then(getData(_id)) 
    .then(showData); 
} 

// returns empty object {} 
function putData(id, data) { 
    return $.ajax({ 
    method: 'PUT', 
    url: http://xxx, 
    contentType: 'application/json' 
    }); 
} 

// returns JSON {"data": {"xx": "xx}} 
function getData(id) { 
    return $.ajax({ 
    method: 'GET', 
    url: http://xxx 
    }); 
} 

function showData(data) { 
    console.log(data); 
} 
+0

註釋不是延長討論;這個對話已經[轉移到聊天](http://chat.stackoverflow.com/rooms/130327/discussion-on-question-by-olefrank-how-to-syncronize-order-of-chained-jquery-pro) 。 –

+0

如何訪問聊天? – olefrank

回答

2

在此代碼:

function doReqs() { 
    putData(_id, data) 
    .then(getData(_id)) 
    .then(showData); 
} 

.then(getData(_id))部分是錯誤的。有兩個原因是錯誤的。

  1. .then()應該傳遞函數引用。當您通過getData(_id)時,您立即執行該函數並將該函數(它是jqXHR對象)的返回值傳遞到.then()。這不是你應該通過.then()

  2. 因爲您正在執行getData(_id),所以它不會在承諾鏈順序中正確執行。

記住,任何時候你通過用括號一個func()後,作爲一個參數,它會立即執行該功能,並將它的返回值作爲參數。由於上述原因,這不是您想要的.then()

如果你想控制被傳遞什麼getData(),那麼你就可以確保正確的事情是從putData()返回,因爲這是將被傳遞到getData()或者你可以做一個存根功能,將通過正確的做法:

function doReqs() { 
    putData(_id, data) 
    .then(function() { 
     return getData(_id); 
    }) 
    .then(showData); 
} 

或者,你可以這樣來做:

function doReqs() { 
    putData(_id, data) 
    .then(getData.bind(null, _id)) 
    .then(showData); 
} 

或者,由於水庫的putData() olved價值是什麼將作爲參數傳遞給在承諾鏈中的下一個步驟(這是getData)通過,你可以這樣做:

function putData(id, data) { 
    return $.ajax({ 
    method: 'PUT', 
    url: http://xxx, 
    contentType: 'application/json' 
    }).then(function() { 
    // make sure putData passes the id to the next step in the chain 
    return id; 
    }); 
} 

function doReqs(id) { 
    putData(id, data) 
    .then(getData) 
    .then(showData); 
} 

這裏的行動鏈的工作示例:

function delay(t, val) { 
 
    return new Promise(function(resolve) { 
 
     setTimeout(resolve.bind(null, val), t); 
 
    }); 
 
} 
 

 
function first(arg) { 
 
    console.log("running first..., arg = ", arg); 
 
    return delay(500, 10); 
 
} 
 

 
function second(arg) { 
 
    console.log("running second..., arg = ", arg); 
 
    return delay(100, 100); 
 
} 
 

 
function third(arg) { 
 
    console.log("running third..., arg = ", arg); 
 
} 
 

 
first(1).then(second).then(third);

+0

添加適當鏈接的工作示例。 – jfriend00

+0

謝謝你的詳細解釋。特別是關於'.then(xx)'中怎麼傳遞什麼'。我現在知道如何解決ajax reqs的執行順序。我最後使用putData()中的'.then()'返回id的最後一個建議。 – olefrank