我如何从函数 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`
}
您正在使用 Ajax 错误. 想法不是要有它返回任何东西,而是将数据转移到所谓的召回功能,处理数据。
这就是:
function handleData( responseData ) {
// Do what you want with the data
console.log(responseData);
}
$.ajax({
url: "hi.php",
...
success: function ( data, status, XHR ) {
handleData(data);
}
});
在提交处理器中返回任何东西不会做任何事情,你必须或者放弃数据,或者直接在成功函数中做你想要的事情。
问题是:
我如何从无同步通话中返回答案?
可以被解释为:
如何让同步代码看起来同步?
解决方案将是避免呼叫,并使用一个组合的承诺和async/await。
我想举一个例子给一个Ajax请求。
(虽然它可以用JavaScript写作,但我宁愿用Python写作,并用Transcrypt编写到JavaScript。
首先,让我们启用 jQuery 使用,以便有 $ 作为 S 可用:
__pragma__ ('alias', 'S', '$')
设置一个函数返回承诺,在这种情况下,一个Ajax呼叫:
def read(url: str):
deferred = S.Deferred()
S.ajax({'type': "POST", 'url': url, 'data': { },
'success': lambda d: deferred.resolve(d),
'error': lambda e: deferred.reject(e)
})
return deferred.promise()
使用非同步代码,就好像它是同步的:
async def readALot():
try:
result1 = await read("url_1")
result2 = await read("url_2")
except Exception:
console.warn("Reading a lot failed")
另一种方法是从无同步函数中返回值,是通过将结果从无同步函数中存储的对象。
下面是相同的例子:
var async = require("async");
// This wires up result back to the caller
var result = {};
var asyncTasks = [];
asyncTasks.push(function(_callback){
// some asynchronous operation
$.ajax({
url: '...',
success: function(response) {
result.response = response;
_callback();
}
});
});
async.parallel(asyncTasks, function(){
// result is available after performing asynchronous operation
console.log(result)
console.log('Done');
});
我正在使用结果对象来存储在无同步操作期间的值,这使得结果即使在无同步工作后也可用。
我使用这个方法很多,我会感兴趣知道这个方法有多好运作,在那里通过连续模块将结果传输回来。
您正在使用 Ajax 错误. 想法不是要有它返回任何东西,而是将数据转移到所谓的召回功能,处理数据。
这就是:
function handleData( responseData ) {
// Do what you want with the data
console.log(responseData);
}
$.ajax({
url: "hi.php",
...
success: function ( data, status, XHR ) {
handleData(data);
}
});
在提交处理器中返回任何东西不会做任何事情,你必须或者放弃数据,或者直接在成功函数中做你想要的事情。
在阅读这里的所有回复和我的经验后,我希望重复在JavaScript中无同步编程的呼叫、承诺和Async/等待的细节。
const body = document.getElementsByTagName('body')[0];
function callback() {
console.log('Hello');
}
body.addEventListener('click', callback);
asyncCallOne(function callback1() {
asyncCallTwo(function callback2() {
asyncCallThree(function callback3() {
...
})
})
})
const myFirstPromise = new Promise((resolve, reject) => {
// We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed.
// In this example, we use setTimeout(...) to simulate async code.
// In reality, you will probably be using something like XHR request or an HTML5 API.
setTimeout(() => {
resolve("Success!") // Yay! Everything went well!
}, 250)
})
myFirstPromise
.then((res) => {
return res.json();
})
.then((data) => {
console.log(data);
})
.catch((e) => {
console.log(e);
});
then — Runs a callback you pass to it when the promise has fulfilled.
catch — Runs a callback you pass to it when something went wrong.
Async 函数为我们提供一个干净和细致的合成,使我们能够写得更少的代码,以实现相同的结果,我们会得到的承诺. Async/Await 看起来类似于同步代码,同步代码更容易阅读和写作。
const getExchangeRate = async () => {
try {
const res = await fetch('https://getExchangeRateData');
const data = await res.json();
console.log(data);
} catch (err) {
console.error(err);
}
}
getExchangeRate();
结论:这些完全是JavaScript中的无同步编程的三个合成,你应该明白,所以如果可能的话,我建议你使用“承诺”或“async/await”来恢复你的无同步代码(主要是XHR请求)!