2015-11-23 5 views
0

Вопрос с новобранец, но я пытаюсь понять, как PapaParse (или что-то еще, если на то пошло) использует обратные вызовы. Когда я использую следующий код:Обратные вызовы в JavaScript

Вот пересмотренный полный код:

<html> 
    <head> 
    <script src="papaparse.js"></script> 
    <script src="drawTable.js"></script> 

</head> 
<body> 
<label>Load CSV file: </label><input type="file" id="fileInputCSV" /><br/> 

    Results: 
    <table id="outputTable" border=1 px> 
     <tbody id="objTable"></tbody> 
    </table> 


    <script type="text/javascript">  
var csvData = []; 
function GetCSV(doneCallback) { 
    var fileInput = document.getElementById('fileInputCSV'); 
     Papa.parse(fileInput.files[0], { 
     header: true, 
     skipEmptyLines: true, 

     complete: function(results) { 
     console.log('Done.'); 
     doneCallback(results); 
    } 
    }); 
} 
} 

GetCSV(function(csvData) { 
    console.table(csvData.data); 
    drawTable(csvData.data, "objTable"); 
}); 
    </script> 
    </body> 
</html> 

Я должен перезагрузить страницу, чтобы получить console.table, и объект, порожденный PapaParse недоступен вне функции PapaParse ,

Я знаю, что это было задано в других формах, но всегда ответили в jQuery. Является ли решение простым JavaScript? Мне действительно нужно не просто отображать данные, но и фактически использовать их.

сам PapaParse заметно тихо на таком базовом использовании их программы ....

Спасибо!

ответ

1

Весь код, который надежно использует асинхронный результат, как только он будет доступен, ДОЛЖЕН быть либо расположен внутри функции обратного вызова завершения, либо должен быть в функции, вызываемой из этой функции обратного вызова.

Это связано с тем, что асинхронный ответ происходит когда-то LATER в неопределенное время. Единственное место в вашем коде, где вы можете точно знать, когда результат готов, находится внутри самого обратного вызова завершения. Это очень плохая практика, чтобы попытаться заполнить асинхронный результат в какой-то более высокой переменной области действия, а затем использовать ее позже, потому что ваш другой код не имеет понятия, когда это значение действительно доступно, что обычно приводит к разным вопросам времени.

Это другой тип программирования, чем последовательное программирование. Вы не просто вызываете getCSV(), а затем используете результаты, полученные на следующей строке кода. Результаты будут доступны не позднее, чем через некоторое время.

Если вы хотите знать, когда результаты в getCSV() были доступны, вы бы построить его так, что он принимает функцию обратного вызова:

function GetCSV(doneCallback) { 
    var fileInput = document.getElementById('fileInputCSV'); 
    Papa.parse(fileInput.files[0], { 
     header: true, 
     skipEmptyLines: true, 

     complete: function(results) { 
      console.log('Done.'); 
      doneCallback(results); 
     } 
    }); 
} 

Затем, вы можете назвать это, как это и потреблять результаты внутри обратного вызова :

GetCSV(function(csvData) { 
    // use the data here 
    drawTable(csvData.data, "objTable"); 
}); 
+0

я могу думать о выдуманных примерах, когда ваше первое утверждение неверно –

+0

@BillyMoon - надуманные примеры? В самом деле? Это то, против чего вы возражаете? В любом случае, я изменил формулировку в этом первом абзаце. – jfriend00

+0

Спасибо! Но я все еще получаю вывод, если перезагружать страницу. – Tyler330

0

Если добавить некоторые console.log заявления в вашей программе вы увидите, что MakeTable становится вызывается перед complete обратного вызова в функции Papa.parse. Этого можно ожидать в Javascript, который не «ждет» для выполнения асинхронных операций перед продолжением. Это означает, что когда вы работаете с обратными вызовами, вы не можете писать функции, которые «возвращаются», когда они будут выполнены. Вместо этого вам нужно написать функции, которые вызывают обратный вызов, когда они будут выполнены.

Один из способов исправить вашу программу, чтобы добавить параметр обратного вызова для вашей функции GetCSV

function getCSV(onDone) { 
    Papa.parse(the_file, { 
     complete: function(results) { 
      consoel.log("got data") 
      onDone(results); //pass our csv to the callback instead 
          //of setting a global variable. 
     } 
    }); 
} 

getCSV(function(csv){ 
    makeTable(csv); 
}); 
Смежные вопросы