在下面的示例中,服务器对doSomethingOne
请求的响应是否可能在服务器响应doSomethingTwo
的请求之前返回?
$scope.pace = $interval (
function() {
// code
}, 1000, 10
).then(postResult)
.then(doSomethingOne)
.then(doSomethingTwo);
问题是因为,doSomethingOne
将数据发布到数据库,然后doSomethingTwo
正在查询数据库并返回一些数据,包括doSomethingOne
应该发布的数据。
但对doSomethingTwo
请求的回复并未包含doSomethingOne
发布的最新数据(直到$scope.pace
从头开始运行)
我对回调没有很强的理解(尽管有很多关于它们的阅读)所以任何建议都会非常感激。
简要说明
doSomthingOne
执行$http.post()
,doSomethingTwo
执行$http.get()
。这里没有使用承诺。
答案 0 :(得分:2)
<强>更新强>:
从你的编辑:
doSomthingOne执行$ http.post()和doSomethingTwo执行$ http.get()。这里没有使用承诺。
好吧,$http.post
returns a promise(有时在文档中称为“未来”),但如果您不使用它,那么在POST之前不会阻止doSomethingTwo
被调用完成了。实际上,在POST完成之前(很久以前)可能会调用非常。
你可以简单地通过返回promise $http.post
返回来解决问题(或者如果你正在使用一个,则返回你对该promise的调用所创建的promise)。 E.g:
function doSomethingOne() {
return $http.post(/*...args...*/);
}
或
function doSomethingOne() {
return $http.post(/*...args...*/).then(/*...*/);
}
以下详情。
原始答案(仍然相关):
这取决于doSomethingOne
做什么以及它返回什么。如果doSomethingOne
启动异步进程但没有返回该进程的承诺,则可以在该进程完成之前调用doSomethingTwo
。如果doSomethingOne
同步工作(根据你所说的不太可能)或返回其异步工作的承诺,它将在调用doSomethingTwo
之前完成,因为doSomethingTwo
等待该承诺得到解决。
以下是doSomethingOne
未返回异步工作承诺的示例,因此doSomethingTwo
可能会在doSomethingOne
的异步工作完成之前运行:
// Simulate an asynchronous DB call
function dbCall(data) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve("Result for " + data);
}, Math.floor(Math.random() * 500));
})
}
function start() {
console.log("start called");
return new Promise(resolve => {
setTimeout(() => {
console.log("start resolving");
resolve();
}, 0);
})
}
function doSomethingOne() {
// THIS IS PROBABLY WRONG
console.log("doSomethingOne called");
dbCall("one data").then(function(result) {
console.log("doSometingOne's async is done");
});
}
function doSomethingTwo() {
console.log("doSomethingTwo called");
}
start().then(doSomethingOne).then(doSomethingTwo);
这可能是错误的。相反,您希望doSomethingOne
从异步工作中返回一个承诺;它可以通过在dbCall(...).then
上返回其调用结果来实现:
// Simulate an asynchronous DB call
function dbCall(data) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve("Result for " + data);
}, Math.floor(Math.random() * 500));
})
}
function start() {
console.log("start called");
return new Promise(resolve => {
setTimeout(() => {
console.log("start resolving");
resolve();
}, 0);
})
}
function doSomethingOne() {
console.log("doSomethingOne called");
return dbCall("one data").then(function(result) {
//^^^^^^^------------------------------------------- change is here
console.log("doSometingOne's async is done");
});
}
function doSomethingTwo() {
console.log("doSomethingTwo called");
}
start().then(doSomethingOne).then(doSomethingTwo);