正常的同步做事方式很简单直接。
但async似乎无法做到这一点。
假设我有一项我想要出售的服务。服务价格因地点而异。
我有一位用户:
代码:
var calcPrice = function(city){
// stuff runs
return price;
};
// Async Function, taken from http://www.zippopotam.us/
// The "place name" is the city.
var returnLocationInfoByZip = function(zip, callback){
var client = new XMLHttpRequest();
var response;
client.open("GET", "http://api.zippopotam.us/us/" + zip, true);
client.onreadystatechange = function() {
if(client.readyState == 4) {
response = client.responseText;
callback(JSON.parse(response));
};
};
client.send();
};
var zip = "94043";
var price = returnLocationInfoByZip(zip, function(response){
calcPrice(response.places[0]["place name"]);
});
// This does not work. I'm going to call this the "dependent processing" part of my code.
functionThatDependsOnPrice(price);
AnotherFunctionThatDependsOnPrice(price);
MoreFunctionsThatDependsOnPrice(price);
EvenMoreFunctionsThatDependOnPrice(price);
// This I THINK would work instead
returnLocationInfoByZip(zip, function(response){
price = calcPrice( response.places[0]["place name"] );
functionThatDependsOnPrice(price);
AnotherFunctionThatDependsOnPrice(price);
MoreFunctionsThatDependsOnPrice(price);
EvenMoreFunctionsThatDependOnPrice(price);
});
在回调中填充所有代码真的很难看并且令人困惑。
我想在普通同步代码中使用 price 变量。但calcPrice
的值永远不会被返回,因此永远不会存储到 price 变量中。 calcPrice
的值永远停留在我的代码流的异步分支中,这迫使我在异步分支/回调中执行所有其他依赖处理。
所以有几个问题:
异步代码永远不能将值返回到同步代码中是否正确?正常的做事和思考的同步方式是行不通的。
胖回调是否正常?
我可以去Promise路线,但如果我这样做,我只是将所有依赖处理填充到我的then
函数中...它看起来有点干净,但它仍然嵌套在其他东西之内。
答案 0 :(得分:1)
异步代码永远无法将值返回到同步代码中是否正确?
是的,差不多。它确实依赖于环境。例如:在浏览器中,像requirejs这样的文件依赖库依赖于异步流。然而,在NodeJS中,它们对它进行了抽象,以便您可以获取同步样式的依赖项(就像使用Java中的Import一样)。
如果您需要从其他Web服务或数据库获取资源,您可能总是需要回调。这是因为javascript引擎的异步性质。每当它从底层环境(例如浏览器)请求资源时,脚本执行都不会停止。因此,您可以同时执行多个异步请求。
胖回调是否正常?
这取决于您的偏好和代码风格。如果它是可读和可维护的,为什么你不应该有一个胖回调?许多人认为这不是很干净。就个人而言,我更喜欢通过实现像Promises这样的东西来实现更扁平的架构。