我将3个ajax请求链接到RESTful端点:
我使用.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 :(得分:2)
在此代码中:
function doReqs() {
putData(_id, data)
.then(getData(_id))
.then(showData);
}
.then(getData(_id))
部分是错误的。这有两个原因。
.then()
应该传递一个函数引用。当您传递getData(_id)
时,您正在立即执行该函数并将该函数的返回值(即jqXHR对象)传递给.then()
。这不是您应该传递给.then()
的内容。
由于您立即执行getData(_id)
,因此无法在承诺链序列中正确执行。
请记住,每当你将func()
后面的parens作为参数传递时,它会立即执行该函数并将其作为参数传递给它。由于上述原因,这不是您想要的.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()
的已解析值将作为参数传递给promise链中的下一步(即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);