我如何从函数 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`
}
如果您不使用 jQuery 在您的代码中,这个答案是为您
function foo() {
var httpRequest = new XMLHttpRequest();
httpRequest.open('GET', "/echo/json");
httpRequest.send();
return httpRequest.responseText;
}
var result = foo(); // Always ends up being 'undefined'
(注意,对于使用新的Fetch API、Angular 或承诺的人,我在下面添加了另一个答案)
你所面临的
这里有一个简单的模拟:
function getFive(){
var a;
setTimeout(function(){
a=5;
},10);
return a;
}
(重定向)
function onComplete(a){ // When the code completes, do this
alert(a);
}
function getFive(whenDone){
var a;
setTimeout(function(){
a=5;
whenDone(a);
},10);
}
使用将是:
getFive(onComplete);
同步AJAX - 不要这样做!!!
var request = new XMLHttpRequest();
request.open('GET', 'yourURL', false); // `false` makes the request synchronous
request.send(null);
if (request.status === 200) {// That's HTTP for 'ok'
console.log(request.responseText);
}
二、修复代码
如:
var result = foo();
// Code that depends on `result` goes here
变成:
foo(function(result) {
// Code that depends on `result`
});
function myHandler(result) {
// Code that depends on `result`
}
foo(myHandler);
function foo(callback) {
var httpRequest = new XMLHttpRequest();
httpRequest.onload = function(){ // When the request is loaded
callback(httpRequest.responseText);// We're calling our method
};
httpRequest.open('GET', "/echo/json");
httpRequest.send();
}
我们现在已经使我们的 foo 函数接受一个行动运行,当 AJAX 成功完成时,我们可以通过检查答案状态是否不为 200 进行进一步扩展,并按照此进行操作(创建一个错误处理器等)。
如果你仍然很难理解这一点,请阅读MDN的AJAX开始指南。
另一个解决方案是通过序列执行器 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 将逐步评估所有运营商和表达式,如果某些缓慢功能的结果不准备好,则停止执行。
这里有更多的例子。
如果您不使用 jQuery 在您的代码中,这个答案是为您
function foo() {
var httpRequest = new XMLHttpRequest();
httpRequest.open('GET', "/echo/json");
httpRequest.send();
return httpRequest.responseText;
}
var result = foo(); // Always ends up being 'undefined'
(注意,对于使用新的Fetch API、Angular 或承诺的人,我在下面添加了另一个答案)
你所面临的
这里有一个简单的模拟:
function getFive(){
var a;
setTimeout(function(){
a=5;
},10);
return a;
}
(重定向)
function onComplete(a){ // When the code completes, do this
alert(a);
}
function getFive(whenDone){
var a;
setTimeout(function(){
a=5;
whenDone(a);
},10);
}
使用将是:
getFive(onComplete);
同步AJAX - 不要这样做!!!
var request = new XMLHttpRequest();
request.open('GET', 'yourURL', false); // `false` makes the request synchronous
request.send(null);
if (request.status === 200) {// That's HTTP for 'ok'
console.log(request.responseText);
}
二、修复代码
如:
var result = foo();
// Code that depends on `result` goes here
变成:
foo(function(result) {
// Code that depends on `result`
});
function myHandler(result) {
// Code that depends on `result`
}
foo(myHandler);
function foo(callback) {
var httpRequest = new XMLHttpRequest();
httpRequest.onload = function(){ // When the request is loaded
callback(httpRequest.responseText);// We're calling our method
};
httpRequest.open('GET', "/echo/json");
httpRequest.send();
}
我们现在已经使我们的 foo 函数接受一个行动运行,当 AJAX 成功完成时,我们可以通过检查答案状态是否不为 200 进行进一步扩展,并按照此进行操作(创建一个错误处理器等)。
如果你仍然很难理解这一点,请阅读MDN的AJAX开始指南。
JavaScript 是单一的 threaded。
浏览器可以分为三个部分:
这是一个对一个进行的曲线,并放入事件圈,执行这个函数,并在第一次执行后为下一个做好准备,这意味着执行一个函数不会开始,直到在事件圈中执行之前的函数。
它从事件路由中取出这个功能,并与服务器进行交易,使事件路由免费,以便我们可以从路由中执行下一个功能。
假设我们的服务器Request()函数有一个返回声明的代码. 当我们从服务器 Web API 恢复数据时,它将推到尾部的尾部。
因此,这个问题的解决方案是召回或承诺。
此分類上一篇
function doAjax(callbackFunc, method, url) {
var xmlHttpReq = new XMLHttpRequest();
xmlHttpReq.open(method, url);
xmlHttpReq.onreadystatechange = function() {
if (xmlHttpReq.readyState == 4 && xmlHttpReq.status == 200) {
callbackFunc(xmlHttpReq.responseText);
}
}
xmlHttpReq.send(null);
}
在我的代码中,它被称为:
function loadMyJson(categoryValue){
if(categoryValue === "veg")
doAjax(print, "GET", "http://localhost:3004/vegetables");
else if(categoryValue === "fruits")
doAjax(print, "GET", "http://localhost:3004/fruits");
else
console.log("Data not found");
}
JavaScript.info 回复