除非使用Ajax或其他东西,否则一直认为javascript不是异步的。我没有使用Ajax调用或任何东西,但我的JS函数似乎不等待返回值:
我有三行代码如下:
var areas = prepareComparer();
console.log('Areas');
console.log(areas);
我需要使用以下函数创建一个overlay 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创建(#compreeree1和#compreree2)时返回数据。但是,由于d3转换是异步的,因此引入了延迟。并且由于新的div仅在转换完成后创建(存在大小依赖性),因此我的main函数无法立即选择新创建的div。
使用JavaScript Promises解决了这个问题:
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');
});
只是想分享解决方案。
答案 0 :(得分:3)
您的函数prepareComparer()
无法返回。在没有返回的JavaScript函数中返回undefined。
setTimeout()
内的回复与prepareComparer()
无关。
除了Ajax,你在这里找到了JavaScript中异步编程的另一个方面。
答案 1 :(得分:-2)
在setTimeout导致函数等待设置时间结束之前放回一个
看起来像这样
return setTimeout(function () { console.log("Hello"); return ['#comparor #comparee1', '#comparor #comparee2'] }, 5000);
抱歉没有工作,但由于你没有返回区域,所以一直都是无人问津的。
对于异步问题,traceur.js引入了一个可能对你有用的await关键字