我如何从函数 foo 返回一个无同步请求的答案/结果?

我正在尝试从呼叫返回的值,以及将结果分配到函数内部的本地变量,并返回其中一个,但没有这些方式实际上返回答案 - 他们都返回不确定的或无论变量结果的初始值是什么。

一个不同步函数的例子,接受召回(使用 jQuery 的 ajax 函数):

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            result = response;
            // return response; // <- I tried that one as well
        }
    });

    return result; // It always returns `undefined`
}

使用 Node.js 的例子:

function foo() {
    var result;

    fs.readFile("path/to/file", function(err, data) {
        result = data;
        // return data; // <- I tried that one as well
    });

    return result; // It always returns `undefined`
}

例如,使用那时承诺的区块:

function foo() {
    var result;

    fetch(url).then(function(response) {
        result = response;
        // return response; // <- I tried that one as well
    });

    return result; // It always returns `undefined`
}

当前回答

另一个解决方案是通过序列执行器 nsynjs 执行代码。

nsynjs 将连续评估所有承诺,并将承诺结果列入数据属性:

函数同步Code() { var getURL = 函数(url) { return window.fetch(url).data.text().data; }; var url = 'https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js'; console.log('收到的比特:',getURL(url).length); }; nsynjs.run(同步Code,{},函数(){ console.log('同步Code done'); }; <script src="https://rawgit.com/amaksr/

如果基本功能不承诺

步骤 1 将函数与呼叫回归到 nsynjs-aware 插槽中(如果它有一个有前途的版本,你可以错过这个步骤):

var ajaxGet = function (ctx,url) {
    var res = {};
    var ex;
    $.ajax(url)
    .done(function (data) {
        res.data = data;
    })
    .fail(function(e) {
        ex = e;
    })
    .always(function() {
        ctx.resume(ex);
    });
    return res;
};
ajaxGet.nsynjsHasCallback = true;

function process() {
    console.log('got data:', ajaxGet(nsynjsCtx, "data/file1.json").data);
}

步骤3:通过 nsynjs 以同步方式运行函数:

nsynjs.run(process,this,function () {
    console.log("synchronous function finished");
});

Nsynjs 将逐步评估所有运营商和表达式,如果某些缓慢功能的结果不准备好,则停止执行。

这里有更多的例子。

其他回答

下面是一個工作的例子: const validateName = async userName => { const url = "https://jsonplaceholder.typicode.com/todos/1"; try { const response = await axios.get(url); return response.data } catch (err) { return false; } }; validateName("user").then(data => console.log(data)).catch(reason => console.log(reason.message)).as-console-wrapper { max-height: 100%!im

角质1

使用AngularJS的人可以通过承诺来处理这种情况。

這裡說,

承诺可以用于无与伦比的功能,并允许一个连接多个功能。

你也可以在这里找到一个好解释。

下面提到的文档中有一个例子。

  promiseB = promiseA.then(
    function onSuccess(result) {
      return result + 1;
    }
    ,function onError(err) {
      // Handle error
    }
  );

 // promiseB will be resolved immediately after promiseA is resolved
 // and its value will be the result of promiseA incremented by 1.

孔子2及以后

在 Angular 2 中,请参见下面的例子,但建议使用 Angular 2 的观察器。

 search(term: string) {
     return this.http
       .get(`https://api.spotify.com/v1/search?q=${term}&type=artist`)
       .map((response) => response.json())
       .toPromise();
}

你可以用这种方式,

search() {
    this.searchService.search(this.searchField.value)
      .then((result) => {
    this.result = result.artists.items;
  })
  .catch((error) => console.error(error));
}

但TypeScript不支持本地ES6承诺,如果你想使用它,你可能需要插件。

此外,这里是承诺的规格。

简单的代码例子将 XHR 在 Node.js 转换为 async-await

var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhttp = new XMLHttpRequest();

function xhrWrapWithPromise() {
  return new Promise((resolve, reject) => {
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4) {
        if (this.status == 200) {
          resolve(this.responseText);
        } else {
          reject(new Error("Couldn't feth data finally"));
        }
      }
    };
    xhttp.open("GET", "https://www.w3schools.com/xml/xmlhttp_info.txt", true);
    xhttp.send();
  });
}

// We need to wrap await in Async function so and anonymous IIFE here
(async _ => {
  try {
    let result = await xhrWrapWithPromise();
    console.log(result);
  } catch (error) {
    console.log(error);
  }
})();

答案简短的是,你必须执行这样的呼叫回复:

function callback(response) {
    // Here you can do what ever you want with the response object.
    console.log(response);
}

$.ajax({
    url: "...",
    success: callback
});

这是其中一个地方,在许多新的JavaScript框架中使用的双向数据连接或存储概念将为您工作。

因此,如果您使用 Angular, React 或任何其他框架,使双向数据连接或存储概念,这个问题只是为您固定,所以简单地说,您的结果在第一阶段是不确定的,所以您在收到数据之前得到了结果 = 不确定的,然后一旦您获得结果,它将被更新并被分配到新的值,你的 Ajax 呼叫的反应。

但是,你如何在纯粹的JavaScript或jQuery中这样做,例如,你在这个问题上问的那样?

例如,在承诺中,我们有某些功能,如成功() 或之后() 将执行,当您的数据为您准备好。

$(document).ready(function(){
    function foo() {
        $.ajax({url: "api/data", success: function(data){
            fooDone(data); // After we have data, we pass it to fooDone
        }});
    };

    function fooDone(data) {
        console.log(data); // fooDone has the data and console.log it
    };

    foo(); // The call happens here
});