这是 Javascript 的常见问题。Javascript 代码必须以连续传递风格编写。它很烦人,但它是你可以转换而不用想太多的东西。
基本上,每当我们有类似的东西时
var x = someSyncFunction(a, b, c);
//do something with x
console.log(x);
我们可以将其转换为异步代码,方法是将函数返回后的所有代码变成一个延续函数,并将 x 从一个变量变成延续回调的参数。
someAsyncFunction(a, b, c, function(x){
//do something with x;
console.log(x);
});
您必须注意它很容易编写令人困惑的代码。要记住的一个好技巧是你可以让你自己的函数也接收回调。这允许它们被不同的函数使用(就像返回值的普通同步辅助函数可以被不同的函数使用)
var getXyz = function(onResult){ //async functions that return do so via callbacks
//you can also another callback for errors (kind of analogous to throw)
$.get('http://www.someurl.com/123=json', function(data) {
var xyz = data.positions[0].latitude;
onResult(xyz); //instead of writing "return xyz", we pass x to the callback explicitely.
});
};
getXyz(function(xyz){ //this would look like "var xyz = getXyz();" if it were sync code instead.
console.log('got xyz');
});
这里的技巧是将函数中的所有返回语句更改为对回调函数的调用。认为好像异步函数从未返回,并且将值返回给某人的唯一方法是将该值传递给回调。
您可能会问为什么没有更简单的方法来完成所有这些工作。好吧,没有,除非您使用另一种语言而不是 Javascript(或者至少可以让您以同步风格编写异步代码但自动编译为常规 Javascript 的语言)