【问题标题】:making synchronous call to async function [duplicate]对异步函数进行同步调用[重复]
【发布时间】:2012-07-21 03:43:05
【问题描述】:

可以说我有这个异步功能:

function fooAsync(){
  callSomeApi(some_args, callbackFunction(results){
    return results; //i want to return the results here after the api call.
  }
}

我正在寻找一种将 prev 函数的返回值分配给 var 的方法,并且只有在我拥有该值时才继续执行代码。

//some code here
var foo = fooAsync();
//some code here after getting back from the async function.

问题在于 foo 将是未定义的,因为 javascript 将在内部异步 api 调用完成之前返回。我知道我可以为此使用回调,但我正在寻找一种方法来“锁定”异步函数并仅在它得到结果时恢复。这样我就不必在异步调用之后将所有代码作为回调传递。

简而言之 - 我如何以常规同步方式从异步 ajax 调用(在我的情况下我调用 google maps api)返回值?

【问题讨论】:

  • 不确定 JS,但在像 C 这样的语言中,您可以阻塞条件变量,直到异步函数完成...
  • 我对在 js 上实现这一点很感兴趣..
  • 你是如何调用 api 的,显示一些代码?简单的解决方案是从一开始就同步调用。
  • @adeneo - 我想将此作为一般性问题,因此特定的 api 与问题无关
  • 你不能在 javascript 中做那种阻塞。您可以将请求转换为同步请求,但这是一个非常糟糕的主意,因为当响应没有及时发生时,它会导致糟糕的用户体验。处理它的更好方法是重新组织代码以异步方式工作。

标签: javascript jquery ajax


【解决方案1】:

通常,使 ajax 调用同步是一个坏主意。您可以设置 XMLHttpRequest 对象上的一个属性(jQuery 允许您轻松执行此操作)以发出同步 ajax 请求。我不确定 google maps API 是否公开了此功能,但您应该先检查那里。

我知道你说过你不想使用回调,但除了做这样的事情:

while(foo === undefined){
  sleep(5) //pseudo code sleep method
}

确实没有任何方法可以锁定当前的执行上下文。

同样使用您提供的代码,该方法将永远不会返回未定义以外的任何内容。您正在调用 api 方法(异步执行)并立即返回控制权。 api 方法调用的响应处理程序内部的“return”语句只会在匿名函数内部返回。因此,即使您能够在结果返回之前锁定线程,您也不会拥有它们。

但是,如果您有兴趣以正确的方式进行此操作,那么您应该使用 jQuery 提供的延迟/承诺模型。

function fooAsync(){
  var deferred = $.Deferred();
  callSomeApi(some_args, callbackFunction(results){
    deferred.resolve(results) //i want to return the results here after the api call.
  }
  return deferred.promise();
}

然后您将调用代码更改为:

//some code here
$.when(fooAsync()).then(function(results){
    //use the results
});
//some code here after getting back from the async function.

jQuery Deferred Object Documentation

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-25
    • 2013-07-12
    • 1970-01-01
    • 2020-10-13
    • 2012-02-25
    • 2020-04-20
    • 1970-01-01
    • 2017-04-07
    相关资源
    最近更新 更多