2014-10-28 77 views
0

正常的同步处理方式非常简单直接。希望对异步JavaScript代码和同步代码进行一些说明

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

但异步似乎不能够做到这一点。

比方说,我有一个服务,我想出售。该服务的价格因地点而异。

我有一个用户:

  • 输入邮编
  • 邮编被发送到一个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); 
}); 

馅都在回调代码是真的很丑陋和混乱。

我想在我的正常同步代码内使用价格变量。但calcPrice的值永远不会返回,因此永远不会存储到变量的价格变量中。 calcPrice的值永远卡在我的代码流的异步分支内,这迫使我在异步分支/回调中执行所有其他依赖处理。

那么几个问题:

  • 它是正确的,异步代码是永远无法返回一个值回同步代码?正常的同步做事和思考事物的方式是行不通的。

  • 脂肪回调是否非常正常?

我可以去无极路线,但如果我这样做,我只是馅所有依赖加工成我then功能......这是一个有点清洁寻找,但它仍然是嵌套在内心深处,其他的事情。

+0

http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call – epascarello 2014-10-28 12:33:49

+0

对我的三个问题,“是”,“是”和“是”? – fuzzybabybunny 2014-10-28 12:35:37

回答

1

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

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

如果您需要从另一个webservice或数据库获取资源,您可能需要一个回调。这是因为javascript引擎的异步性质。只要从底层环境(例如浏览器)请求资源,脚本执行就不会停止。因此,您可以同时执行多个异步请求。

脂肪回调是否非常正常?

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

+0

感谢您的回答!是的,我认为Promises是两个恶魔中较小的一个。请注意,您是否遇到Promise在浏览器上不受支持的任何重大问题?关于Promises的官方MDN文件有一个很大的声明,那就是实验技术。 – fuzzybabybunny 2014-10-28 12:41:25

+0

有各种承诺库不依赖于实验性浏览器功能。一些臭名昭着的是:** Q **(https://github.com/kriskowal/q)和** jQuery Deferred **(http://api.jquery.com/category/deferred-object/)。另外,我没有提到'XMLHTTPRequest'实际上有一个使请求同步的参数,但是如果请求超时,这又可能导致你所有其他的麻烦。 – Hless 2014-10-28 12:48:01

+0

哈哈,他们臭名昭着?那么远离他们? – fuzzybabybunny 2014-10-28 12:48:50