如何在ajax调用结果出来之后返回函数的值?

时间:2022-01-10 23:56:42

Sort of like this:

有点像:

function getfoo() {
  var foo = "";
  $.get("foofile.html", function (data) {
    foo = data;
  });
  return foo;
}

But then since the script is asynchronous, it will return "". That's obviously not what I want.

但是,由于脚本是异步的,它将返回“”。那显然不是我想要的。

So then I tried this:

那么我试过这个:

function getfoo() {
  var foo = "";
  $.get("foofile.html", function (data) {
    foo = data;
  });
  for (;;) {
    if (foo != "") {
      return foo;
      break;
    }
  }
}

And I expected that to work, but it didn't. Why not? And can someone suggest a solution?

我希望它可以工作,但事实并非如此。为什么不?有人可以提出解决方案吗?

3 个解决方案

#1


2  

You should use a callback pass to the function and let it deal your data.

您应该使用函数的回调传递,让它处理您的数据。

function getfoo(callback) {
  var foo = "";
  $.get("foofile.html", function (data) {
    callback(data);
    // do some other things
    // ...
  });
}

getfoo(function(data) {
   console.log(data);
});

#2


1  

When using ajax, you should write your code a little bit differently. You should separate your caller and callee logic.

使用ajax时,您应该以不同的方式编写代码。您应该将调用者和被调用者逻辑分开。

Suppose your existing code is like

假设您的现有代码是这样的

function getfoo() {
  var foo = "";
  $.get("foofile.html", function (data) {
    foo = data;
  });
  return foo;
}

function usefoo(){
  var data = getfoo();
  // do something with data
}

It should really be written like

它应该真的写得像

function getfoo() {
  var foo = "";
  $.get("foofile.html", function (data) {
    usefoo(data);
  });
}

function usefoo(data){
  // do something with data
}

#3


1  

The first "a" of ajax stands for asynchronous and so what you are trying to do is sort of against the philosophy of ajax. However it is possible to use a blocking request but this is not supported by the .get simplified interface and you must use the .ajax function:

ajax的第一个“a”代表异步,所以你要做的就是反对ajax的哲学。但是,可以使用阻止请求,但.get简化接口不支持此功能,您必须使用.ajax函数:

var foo = "hmmm";
$.ajax("jquery.js", {async:false, success:function(x){foo=x}});
alert(foo);

The basic execution model of javascript is event-based and single threaded (there are web workers that provide multithreading capability, but each worker lives in its own address space and cannot share any memory with other workers or with the main thread... so in a sense they're more similar to processes than to threads).

javascript的基本执行模型是基于事件和单线程的(有些Web工作者提供多线程功能,但每个工作者都在自己的地址空间中,不能与其他工作者或主线程共享任何内存......所以从某种意义上讲,它们与流程相似而不是与线程相似。

In Javascript your cannot "wait" in a loop for other things to happen, you functions must always terminate quickly, possibly attaching callbacks to be called again when something happens. If you make a loop the javascript engine will just get stuck in that loop and is not allowed to do other processing (if that is visible from javascript). For example:

在Javascript中你不能在循环中“等待”其他事情发生,你的函数必须总是快速终止,可能附加回调以便在事情发生时再次调用。如果你创建一个循环,javascript引擎将陷入该循环,并且不允许进行其他处理(如果从javascript可见)。例如:

// Warning: WRONG example... this won't work!
var foo = 0;
setTimeout(function(){foo = 1}, 100); // Set foo=1 after 100ms
while (foo == 0) ; // Wait for that to happen
alert(foo);

is NOT going to work, because the browser engine is not allowed to execute other javascript code (the timeout callback) until the main code path gets to an end.

不会工作,因为浏览器引擎不允许执行其他javascript代码(超时回调),直到主代码路径结束。

This event-based approach simplifies programming quite a bit (because there's no locking needed... there's always just one single thread manipulating the state) but forces to use a different flow design for long operations.

这种基于事件的方法简化了编程(因为不需要锁定......总是只有一个线程操纵状态)但强制使用不同的流程设计进行长时间操作。

The fact that there is a single thread of execution also means that while your javascript code is doing any long computation everything else is blocked and the browser looks unresponsive for the user.

存在单个执行线程的事实也意味着当您的javascript代码执行任何长计算时,其他所有内容都被阻止,并且浏览器看起来对用户没有响应。

This unresponsiveness is why the use of synchronous calls to retrieve resources is considered a bad practice... the difficult job of concurrent acquisition of different resources from multiple streams is already implemented by the browser but your javascript code is required to use a callback model to be able to take advantage of this feature.

这种反应迟钝的原因是使用同步调用来检索资源被认为是一种不好的做法...浏览器已经实现了从多个流并发获取不同资源的困难工作,但是你的javascript代码需要使用回调模型来实现能够利用此功能。

#1


2  

You should use a callback pass to the function and let it deal your data.

您应该使用函数的回调传递,让它处理您的数据。

function getfoo(callback) {
  var foo = "";
  $.get("foofile.html", function (data) {
    callback(data);
    // do some other things
    // ...
  });
}

getfoo(function(data) {
   console.log(data);
});

#2


1  

When using ajax, you should write your code a little bit differently. You should separate your caller and callee logic.

使用ajax时,您应该以不同的方式编写代码。您应该将调用者和被调用者逻辑分开。

Suppose your existing code is like

假设您的现有代码是这样的

function getfoo() {
  var foo = "";
  $.get("foofile.html", function (data) {
    foo = data;
  });
  return foo;
}

function usefoo(){
  var data = getfoo();
  // do something with data
}

It should really be written like

它应该真的写得像

function getfoo() {
  var foo = "";
  $.get("foofile.html", function (data) {
    usefoo(data);
  });
}

function usefoo(data){
  // do something with data
}

#3


1  

The first "a" of ajax stands for asynchronous and so what you are trying to do is sort of against the philosophy of ajax. However it is possible to use a blocking request but this is not supported by the .get simplified interface and you must use the .ajax function:

ajax的第一个“a”代表异步,所以你要做的就是反对ajax的哲学。但是,可以使用阻止请求,但.get简化接口不支持此功能,您必须使用.ajax函数:

var foo = "hmmm";
$.ajax("jquery.js", {async:false, success:function(x){foo=x}});
alert(foo);

The basic execution model of javascript is event-based and single threaded (there are web workers that provide multithreading capability, but each worker lives in its own address space and cannot share any memory with other workers or with the main thread... so in a sense they're more similar to processes than to threads).

javascript的基本执行模型是基于事件和单线程的(有些Web工作者提供多线程功能,但每个工作者都在自己的地址空间中,不能与其他工作者或主线程共享任何内存......所以从某种意义上讲,它们与流程相似而不是与线程相似。

In Javascript your cannot "wait" in a loop for other things to happen, you functions must always terminate quickly, possibly attaching callbacks to be called again when something happens. If you make a loop the javascript engine will just get stuck in that loop and is not allowed to do other processing (if that is visible from javascript). For example:

在Javascript中你不能在循环中“等待”其他事情发生,你的函数必须总是快速终止,可能附加回调以便在事情发生时再次调用。如果你创建一个循环,javascript引擎将陷入该循环,并且不允许进行其他处理(如果从javascript可见)。例如:

// Warning: WRONG example... this won't work!
var foo = 0;
setTimeout(function(){foo = 1}, 100); // Set foo=1 after 100ms
while (foo == 0) ; // Wait for that to happen
alert(foo);

is NOT going to work, because the browser engine is not allowed to execute other javascript code (the timeout callback) until the main code path gets to an end.

不会工作,因为浏览器引擎不允许执行其他javascript代码(超时回调),直到主代码路径结束。

This event-based approach simplifies programming quite a bit (because there's no locking needed... there's always just one single thread manipulating the state) but forces to use a different flow design for long operations.

这种基于事件的方法简化了编程(因为不需要锁定......总是只有一个线程操纵状态)但强制使用不同的流程设计进行长时间操作。

The fact that there is a single thread of execution also means that while your javascript code is doing any long computation everything else is blocked and the browser looks unresponsive for the user.

存在单个执行线程的事实也意味着当您的javascript代码执行任何长计算时,其他所有内容都被阻止,并且浏览器看起来对用户没有响应。

This unresponsiveness is why the use of synchronous calls to retrieve resources is considered a bad practice... the difficult job of concurrent acquisition of different resources from multiple streams is already implemented by the browser but your javascript code is required to use a callback model to be able to take advantage of this feature.

这种反应迟钝的原因是使用同步调用来检索资源被认为是一种不好的做法...浏览器已经实现了从多个流并发获取不同资源的困难工作,但是你的javascript代码需要使用回调模型来实现能够利用此功能。