Javascript不等待返回值

Javascript不等待返回值,javascript,jquery,ajax,d3.js,Javascript,Jquery,Ajax,D3.js,一直认为javascript不是异步的,除非使用Ajax或其他东西。我没有使用Ajax调用或任何东西,但我的JS函数似乎没有等待返回值: 我有三行代码,如下所示: var areas = prepareComparer(); console.log('Areas'); console.log(areas); 我需要使用以下函数创建一个覆盖div: function prepareComparer() { var comparorSelection = d3.select('body')

一直认为javascript不是异步的,除非使用Ajax或其他东西。我没有使用Ajax调用或任何东西,但我的JS函数似乎没有等待返回值:

我有三行代码,如下所示:

var areas = prepareComparer();
console.log('Areas');
console.log(areas);
我需要使用以下函数创建一个覆盖div:

function prepareComparer() {
    var comparorSelection = d3.select('body').append('div').attr('id', 'comparor').attr('style', 'line-height: 100px;position: fixed;top: 5%; left:5%;background-color: white;border-radius: 5px;text-align: center;z-index: 2;border-style:solid;border-width:1px;box-shadow: 10px 10px 5px #888888')
        .transition().duration(500).style('height', '800px').style('width', $(window).width() * .9 + 'px').style('opacity', '1').each('end', function () {
            //Waiting for end of transition to append the comparees: Otherwise, causes size adjustment problems since comparee sizes depend on the FULL height.
            d3.select('#comparor').append('div').attr('id', 'comparee1').attr('style', 'position:absolute;top:0px;left:0px;width:' + $('#comparor').width() * .45 + 'px;height:' + $('#comparor').height() + 'px')
            .append('svg');
            d3.select('#comparor').append('div').attr('id', 'comparee2').attr('style', 'position:absolute;top:0px;left:' + $('#comparor').width() * .5 + 'px;width:' + $('#comparor').width() * .45 + 'px;height:' + $('#comparor').height() + 'px')
            .append('svg');
            d3.select('#comparor').append('div').attr('id', 'destroyComparor').text('Click Here To Go Back').on('click', function () {
                d3.select('#comparor').transition().duration(500).style('width', '0px').style('height', '0px').style('opacity', '0').remove();
            });
        });
    setTimeout(function () { console.log("Hello"); return ['#comparor #comparee1', '#comparor #comparee2'] }, 5000);
}
现在,我的日志显示为:

Areas 
undefined 
Hello 
忽略d3代码,因为注释或取消注释似乎没有多大区别。为了确定,我引入了5秒的超时时间。因此,5秒钟后,我收到了Hello消息,这意味着返回也可能在这之后发生。我几乎立刻收到了未定义的消息

我不太清楚为什么会发生这种情况,多年来我一直在试图破解这种情况。有人能帮忙吗

编辑

希望在代码中返回完成新div创建时的数据(#comparee1和#comparee2)。但是,由于d3转换是异步的,因此引入了延迟。由于新的div仅在转换完成后创建(存在大小依赖关系),因此我的主函数无法立即选择新创建的div

通过使用JavaScript承诺解决了此问题:

function prepareComparer() {
    promise = new Promise(function (resolve, reject) {
        var comparorSelection = d3.select('body').append('div').attr('id', 'comparor').attr('style', 'line-height: 100px;position: fixed;top: 5%; left:5%;background-color: white;border-radius: 5px;text-align: center;z-index: 2;border-style:solid;border-width:1px;box-shadow: 10px 10px 5px #888888')
        .transition().duration(500).style('height', '800px').style('width', $(window).width() * .9 + 'px').style('opacity', '1').each('end', function () {
            //Waiting for end of transition to append the comparees: Otherwise, causes size adjustment problems since comparee sizes depend on the FULL height.
            d3.select('#comparor').append('div').attr('id', 'comparee1').attr('style', 'position:absolute;top:0px;left:0px;width:' + $('#comparor').width() * .45 + 'px;height:' + $('#comparor').height() + 'px')
            .append('svg');
            d3.select('#comparor').append('div').attr('id', 'comparee2').attr('style', 'position:absolute;top:0px;left:' + $('#comparor').width() * .5 + 'px;width:' + $('#comparor').width() * .45 + 'px;height:' + $('#comparor').height() + 'px')
            .append('svg');
            d3.select('#comparor').append('div').attr('id', 'destroyComparor').text('Click Here To Go Back').on('click', function () {
                d3.select('#comparor').transition().duration(500).style('width', '0px').style('height', '0px').style('opacity', '0').remove();
            });
            resolve(['#comparor #comparee1', '#comparor #comparee1']);
        });
    });
}
使用数据的函数将被称为:

promise.then(function (response) {
     window[func](response[0], res, 'label', 'value');
});

只是想分享解决方案。

在设置超时之前放置一个返回,因为函数将等待设置超时完成

像这样

return setTimeout(function () { console.log("Hello"); return ['#comparor #comparee1', '#comparor #comparee2'] }, 5000);
抱歉不起作用,但由于您没有返回区域,因此该区域将始终未被定义


对于异步问题,traceur.js引入可能对您有用的wait关键字

您的函数
prepareComparer()
没有返回。在JavaScript函数中,如果没有返回,则返回未定义

setTimeout()
中的返回与
prepareComparer()
无关


在这里,除了Ajax之外,您还发现了JavaScript中异步编程的另一个方面。

计时器是异步的——JavaScript中也不只是这两个东西是异步的。这将返回超时id,而不是OP试图返回的数据。