想要对异步javascript代码与同步代码进行一些澄清

时间:2014-10-28 12:25:32

标签: javascript asynchronous

正常的同步做事方式很简单直接。

  • 一个函数接收输入。
  • 该功能使用这些输入执行操作。
  • 该函数弹出一个值(返回一个值)。
  • 弹出的值可以存储到变量中,直接用于同步代码的其他部分等。

但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函数中...它看起来有点干净,但它仍然嵌套在其他东西之内。

1 个答案:

答案 0 :(得分:1)

异步代码永远无法将值返回到同步代码中是否正确?

是的,差不多。它确实依赖于环境。例如:在浏览器中,像requirejs这样的文件依赖库依赖于异步流。然而,在NodeJS中,它们对它进行了抽象,以便您可以获取同步样式的依赖项(就像使用Java中的Import一样)。

如果您需要从其他Web服务或数据库获取资源,您可能总是需要回调。这是因为javascript引擎的异步性质。每当它从底层环境(例如浏览器)请求资源时,脚本执行都不会停止。因此,您可以同时执行多个异步请求。

胖回调是否正常?

这取决于您的偏好和代码风格。如果它是可读和可维护的,为什么你不应该有一个胖回调?许多人认为这不是很干净。就个人而言,我更喜欢通过实现像Promises这样的东西来实现更扁平的架构。