javascript命令asyn函数

时间:2018-04-08 15:11:50

标签: javascript jquery

我目前正在修改一个开源项目(link)以满足我的需求。

我的英文不好,也许如果你点击链接页面会更清楚,加载需要半分钟,浏览器可能会冻结片刻。

此页面使用slickgrid,当鼠标悬停在表格行上时,它将在页面上的固定位置图层(左下角)呈现该行的详细信息。页面上只有一个这样的细节层,当您将鼠标移动到另一行时,该图层将更改为显示该行的详细信息。以下代码是如何实现这一目标的:

this.grid.onMouseEnter.subscribe( function (e) {})  // use slickgrid to set event listeners
// inside the handler function
from event e, get the row number row.rc 
// then calls the staticOverlayDetails function do the actual  work. it will renders the presentation layer.
window.setTimeout(function(){staticOverlayDetails(rc.row);}, 30);

因此,此staticOverlayDetails函数将呈现图层(div元素)以显示行号rc.row的详细信息,这是鼠标光标所在的位置。

我想收集所有渲染的结果层html代码,以便我可以将它们组合成一个页面以便于阅读。这意味着,我想将鼠标悬停在第一行,等待渲染图层,复制并保存div元素,然后将鼠标移动到下一行,等待使用此新行渲染图层,...重复直到所有行完成。

函数staticOverlayDetails伪代码:

function staticOverlayDetails (rown) {
     //step 1:generate html text structure for the row, but leaves an element blank, this element is a text description for the row. the text will be loaded from a txt file
     ...
     ...

     // html_text contains an `div` for description text which is currently empty,  the text need to be fetched from a text file url, the text file name is based on the content of row. for the purpose of when the text is fetched, the callingback function need to know where to insert and avoid insert wrongly ( if the mouse has already moved to another row, the layer is showing details of another row, so the description text mismatch), so here it set a random string as the unique id of the description `div`, so later the `insert` function can use the id string as selector to insert text.
     description_selector = random_id
     html_text= html_code_generated

     //step 2:
     // this function fetches a  , setting a callback function `insert` to insert the content.
     url=generate text file url from row content
     load_description( url, description_selector )
     //step 3: present html
     $(fixed-layer).html(txt)
     //at this time , the description div is blank. the callback function will insert content into div when fetched.
}

function load_description (url, description_selector) {

     function insert ( descrp_text ) {
          $(description_selector).html(descrp_text).hide.slide_down()
     }
     $.get(url, insert, 'text')
}

我的计划是循环rown来更改固定图层,然后转出固定图层:

for ( i=0; i < row_counts ; i++ ){
     staticOverlayDetails(i)
     console.log($(fixed_layer_selector).html())

但是异步$.get()调用使得此尝试无法进行。因为只有当insert函数完成时,图层中的内容才是稳定的并且可以转储,如果我使用这个循环,当$.get返回时,表示层已经显示了后面的图层,我不知道知道如何等待它。

如何让我的代码等待$.get()的回调函数完成,这样我就可以保存行的完整细节,然后继续循环下一行?

根据link,我尝试修改函数$.get同步中的load_content_for_an_element请求:

function load_description (url, description_selector) {

     function insert ( descrp_text ) {
          $(description_selector).html(descrp_text).hide.slide_down()
     }

     $.get({url:url, success:insert, sync:false});

}

但浏览器向https://host.address/[object%20Object]发出请求,并返回404错误。似乎它将传递的对象转换为字符串,然后将其视为要获取的URL。

其他一些信息:

1,因为这个项目有几个表,每个表都有不同的渲染逻辑,我想让变化尽可能小,这就是我想要转储生成的表示层而不是改变生成代码本身的原因。所有不同的表都呈现相同的层,这是最简单的方法。

2,我想转储代码生成一个页面来读取,只需要转储一次,所以不用担心性能问题。实际上我可以使用鼠标宏来做到这一点,但我认为这太愚蠢了,我想学习javascript方式来做到这一点:)

我很抱歉我的英语不好而且我想表达这么复杂的情况,所以如果我的话不清楚请求更多的信息,我很遗憾看到其他人因为我的错误而浪费时间话...

1 个答案:

答案 0 :(得分:1)

Promises是你的朋友。以下是如何构建代码以使用它们的示例:

// Set up a staging area
var staticOverlays = [];
loadStaticOverlayDetails(index) {
  return $.get(url, insert, data....).then(function (data) {
    staticOverlays[index] = data;
  });
}

// Request your data
var promises = [];
for ( var i=0; i < 100; i++ ) {
     promises.push(loadStaticOverlayDetails(i));
}

// Wait for the data to complete loading
$.when(promises).then(function insert() {
  for ( i=0; i < staticOverlays.length; i++ ) {
    var overlay = staticOverlays[i];

    // step 1:generate html text structure for the row, but leaves an element blank
    var txt = html_code_generated

    // insert data into element in fixed layer;
    $(fixed-layer).html(txt);
  }
});

顺便说一句,如果你真的要发出100多个http请求,你应该考虑将这些逻辑移到服务器上,因为许多http请求会损害你的用户体验......