我如何从函数 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`
}
短答:您的 foo() 方法即时返回,而 $ajax() 通话在函数返回后无同步执行。
也许最简单的方式是将对象转移到 foo() 方法,并在 async 呼叫完成后将结果存储在该对象的一个成员中。
function foo(result) {
$.ajax({
url: '...',
success: function(response) {
result.response = response; // Store the async result
}
});
}
var result = { response: null }; // Object to hold the async result
foo(result); // Returns before the async completes
请注意,对 foo() 的呼叫仍然不会有用,但是,对 async 呼叫的结果现在将存储在 result.response 中。
虽然承诺和呼叫在许多情况下工作顺利,但背部疼痛是表达这样的东西:
if (!name) {
name = async1();
}
async2(name);
您最终会通过 async1; 检查名称是否不定义,并根据此呼叫回复。
async1(name, callback) {
if (name)
callback(name)
else {
doSomething(callback)
}
}
async1(name, async2)
雖然在小例子中很好,但當你有許多類似案例和錯誤處理涉及時,它會變得令人不安。
纤维可以帮助解决这个问题。
var Fiber = require('fibers')
function async1(container) {
var current = Fiber.current
var result
doSomething(function(name) {
result = name
fiber.run()
})
Fiber.yield()
return result
}
Fiber(function() {
var name
if (!name) {
name = async1()
}
async2(name)
// Make any number of async calls from here
}
您可以在此处查看项目。
使用 async/await 与一个 transpilers 如 Babel 让它工作在较老的浏览器. 你还需要安装这个 Babel 预定和 polyfill 从 npm: npm i -D babel-preset-env babel-polyfill。
function getData(ajaxurl) {
return $.ajax({
url: ajaxurl,
type: 'GET',
});
};
async test() {
try {
const res = await getData('https://api.icndb.com/jokes/random')
console.log(res)
} catch(err) {
console.log(err);
}
}
test();
或者.then callback 只是写同样的逻辑的另一种方式。
getData(ajaxurl).then(function(res) {
console.log(res)
}
短答:您的 foo() 方法即时返回,而 $ajax() 通话在函数返回后无同步执行。
也许最简单的方式是将对象转移到 foo() 方法,并在 async 呼叫完成后将结果存储在该对象的一个成员中。
function foo(result) {
$.ajax({
url: '...',
success: function(response) {
result.response = response; // Store the async result
}
});
}
var result = { response: null }; // Object to hold the async result
foo(result); // Returns before the async completes
请注意,对 foo() 的呼叫仍然不会有用,但是,对 async 呼叫的结果现在将存储在 result.response 中。