Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/480.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript/JQuery:避免异步函数/匿名回调函数嵌套的最佳方法_Javascript_Asynchronous - Fatal编程技术网

JavaScript/JQuery:避免异步函数/匿名回调函数嵌套的最佳方法

JavaScript/JQuery:避免异步函数/匿名回调函数嵌套的最佳方法,javascript,asynchronous,Javascript,Asynchronous,我的JavaScript代码包含很多异步函数。例如,我使用D3.JS读取CSV文件,并连接到Google Maps API以查找两个地址之间的行驶方向 我使用on StackOverflow来等待异步函数完成(以避免返回带有未定义值的变量)。但是,因为我有很多异步函数,所以我有很多嵌套的匿名回调函数: carDirections(from, to).done(function(car) { transitDirections(from, to).done(function

我的JavaScript代码包含很多异步函数。例如,我使用D3.JS读取CSV文件,并连接到Google Maps API以查找两个地址之间的行驶方向

我使用on StackOverflow来等待异步函数完成(以避免返回带有
未定义值的变量)。但是,因为我有很多异步函数,所以我有很多嵌套的匿名回调函数:

    carDirections(from, to).done(function(car) {
        transitDirections(from, to).done(function(train) {
        // carDirections and trainDirections have similar anonymous callback functions.

    function carDirections(from, to) {
        var dfd = $.Deferred();

        var directionsService = new google.maps.DirectionsService;

        directionsService.route({
            origin: from,
            destination: to,
            travelMode: google.maps.TravelMode.DRIVING
        }, function(response, status) {
            if (status === google.maps.DirectionsStatus.OK) {
                dfd.resolve(response.routes[0].legs[0]);
            }
        });

        return dfd.promise();
    }
    // Similar code for transitDirections.

这导致了大量的
done
Deferred
函数,这使得代码很难理解。有没有合适的方法来解决这个问题?例如,我可以重新编程我的谷歌地图功能,使其同步,还是有其他功能(更简单)只有在上一个函数返回变量时才继续执行代码的方法?

据我所知,列车方向不需要从CardDirections获得任何响应,您只需要在所有操作完成后启动回调

您可以使用延迟对象

var deferredObj1 = $.Deferred(),
    deferredObj2 = $.Deferred();

$.when(deferredObj1,deferredObj2).done(function(){
    console.log("They are both done!");
});

// inside the Event1 handler:
deferredObj1.resolve();

// inside the Event2 handler:
deferredObj2.resolve();
jQuery1.5中引入的延迟对象是一个可链接的实用程序 通过调用jQuery.Deferred()方法创建的对象。它可以 将多个回调注册到回调队列中,调用回调 队列,并中继任何同步或 异步函数

您可能想了解更多关于
Promise
s的内容。您可以像这样链接异步操作

asyncOp1()
  .then(result1 => asyncOp2(result1))
  .then(result2 => asyncOp3(result2))
  .then(result3 => Promise.all(asyncOp4(result3), asyncOp5(result3)))
  .catch(error => { /* deal with an error */ })
  // ...
如果所有操作都返回
承诺
(这有助于避免嵌套)。(上述ES5伪代码和
承诺(如果需要)。



如果您正在寻找不同的方法来处理复杂的异步代码,请查看。。。这并不是说如果你这样做,我会承担任何责任:)

你有没有研究过承诺?@blessenm是的,这就是我在上面的帖子中尝试的。这导致了大量的承诺,我想知道这是否可以避免。这似乎是一个很好的解决方案,谢谢!但是,如果我有以下代码:
carDirections(from,to).then(car=>trainDirections(from,to)).then(train=>console.log(car)),变量
car
不再可访问。除了将此变量作为函数参数发送外,还有其他方法可以继续传递此变量吗?您可以将其保存到外部作用域变量或扩展
Promise
monad以收集链中的所有结果,但只发送所需的内容是最简单和最透明的。如果你不想污染你的火车操作功能,你可以一直做
carOp()。然后(car=>trainOp(car)。然后(train=>({car,train}))。然后({car,train})=>…)