正常的同步处理方式是很好而且简单的。
- 函数接受输入。
- 该函数使用这些输入执行操作。
- 该函数弹出一个值(返回一个值)。
- 弹出的值可以存储到变量中,直接在同步代码的其他部分使用等。
但是 async 似乎无法做到这一点。
假设我有一项想要出售的服务。服务价格因地点而异。
我有一个用户:
- 输入邮政编码
- 邮政编码被发送到 API,同时返回城市名称。
- 我使用城市名称来运行一个返回价格的超大型函数。
- 然后,我想在同步代码的其他部分使用价格,而该同步代码非常长,并且跨越许多函数,而这些函数都依赖于价格值。
代码:
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
函数中......它看起来更干净一些,但它仍然嵌套在内部深处其他事情。
最佳答案
异步代码永远无法将值返回到同步代码中,这是否正确?
是的,差不多。但这确实取决于环境。例如:在浏览器中,像 requirejs 这样的文件依赖库依赖于异步流程。然而,在 NodeJS 中,他们将其抽象化,以便您可以同步方式获取依赖项(就像 Java 中的 Import 一样)。
如果您需要从另一个网络服务或数据库获取资源,您可能总是需要回调。这是因为 JavaScript 引擎的异步特性。每当脚本从底层环境(例如浏览器)请求资源时,脚本执行都不会停止。因此,您可以同时执行多个异步请求。
回调很正常吗?
这取决于您的偏好和代码风格。如果它是可读且可维护的,为什么不应该有一个胖回调呢?许多人会认为这不干净。就我个人而言,我更喜欢通过实现 Promises 之类的东西来获得更扁平的架构。
关于javascript - 需要一些关于异步 javascript 代码与同步代码的澄清,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26608332/