javascript - 需要一些关于异步 javascript 代码与同步代码的澄清

标签 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 函数中......它看起来更干净一些,但它仍然嵌套在内部深处其他事情。

最佳答案

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

是的,差不多。但这确实取决于环境。例如:在浏览器中,像 requirejs 这样的文件依赖库依赖于异步流程。然而,在 NodeJS 中,他们将其抽象化,以便您可以同步方式获取依赖项(就像 Java 中的 Import 一样)。

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

回调很正常吗?

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

关于javascript - 需要一些关于异步 javascript 代码与同步代码的澄清,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26608332/

相关文章:

javascript - 在nodejs中将变量从一个js传递到另一个js文件

javascript - 在 Django 模板中使用 for 循环显示多个 chart.js 图表

javascript - 将箭头函数分配给变量后导出与直接导出有什么区别?

javascript - 没有 MicrosoftAjax.js 和 MicrosoftMvcAjax.js 的 ASP.NET MVC

javascript - 如何在单击 TR 时选择它并在单击另一个 TR 时删除选择

node.js - 运行 forEach 后返回变量

iOS:NSURLConnection sendAsynchronousRequest 对 NSImageView 的延迟操作

javascript - 使用队列处理异步回调

c# - 使用 async/await 和 TaskCompletionSource 的奇怪堆栈跟踪增长

c# - 返回给调用者的异步结果句柄