2017-12-13 38 views
0

私は、同期して動作する次のコードを持っています。基本的に、それはHTMLフォームを受け入れ、その要素をURL文字列に解析します。JavaScript:同期コードで非同期FileReaderを使用するには?

SmFaq.DataForm = function (f) { // f is HTML form 
    var P = new Array(); 

    /* parsing array */ 

    var params = P.join("&"); 
    return params; 
} 

これはうまく機能しましたが、今はinput type="file"を追加する必要があります。私はこの記事に基づいてリクエストしました:Sending forms with JavaScriptバイナリデータの扱い)リクエスト本体にバイナリデータをロードする以外はすべて正常に動作します。私の関数は、ファイルが読み込まれる前に文字列を返します。

タスク:身体の文字列を要求するためにバイナリデータを読み込んで追加する必要があります。返すこの文字列。出来ますか?私はGUIが読み込み時間のためにフリーズするかどうか気にしない。

は、ここに私のコードです:

SmFaq.DataForm = function (f) { 

    var name = f.querySelector('#created_by'); 
    var email = f.querySelector('#created_by_email'); 
    var question = f.querySelector('#question'); 
    var file = { 
     dom: f.querySelector('#file'), 
     binary: null 
    }; 

    var reader = new FileReader(); // to read binary data 


    if (file.dom.files[0]) { 
     reader.readAsBinaryString(file.dom.files[0]); 
    } 

    file.dom.addEventListener('change', function() { 
    if (reader.readyState === FileReader.LOADING) { 
     reader.abort(); 
    } 

     reader.readAsBinaryString(file.dom.files[0]); 
    }); 

    reader.addEventListener('loadend', function() { 
     file.binary = reader.result; 
     console.log('Binary data loaded!'); 
    }); 

    return sendData(); 

    function sendData() { 

     if (!file.binary && file.dom.files.length > 0) { 
      setTimeout(sendData, 2000); 
      return; 
     } 


     var boundary = "1234567890"; 

     var data = ''; 

     data += '--' + boundary + '\r\n'; 
     data += 'content-disposition: form-data; ' 
     + 'name="' + file.dom.name + '";' 
     + 'filename="' + file.dom.files[0].name + '"\r\n'; 
     data += 'Content-Type: ' + file.dom.files[0].type + '\r\n'; 
     data += '\r\n'; 
     data += file.binary + '\r\n'; 

     data += '--' + boundary + '\r\n'; 
     data += 'content-disposition: form-data; name="' + name.name + '"\r\n'; 
     data += '\r\n'; 
     data += name.value + '\r\n'; 

     data += '--' + boundary + '\r\n'; 
     data += 'content-disposition: form-data; name="' + email.name + '"\r\n'; 
     data += '\r\n'; 
     data += email.value + '\r\n'; 

     data += '--' + boundary + '\r\n'; 
     data += 'content-disposition: form-data; name="' + question.name + '"\r\n'; 
     data += '\r\n'; 
     data += question.value + '\r\n'; 
     data += '--' + boundary + '--'; 
     data += '\r\n'; 

     return data; 
    } 
} 

予想通り、それは確かに動作していないので、私はこの非同期の事を知りません。

PleseはES7機能を使用していません。私は従来のコードを使用しており、Babelを使用する可能性はありません。

+1

"可能ですか?" - いいえ。 – Quentin

+0

代わりにformdataを使用してください!あなたが[mine](https://github.com/jimmywarting/FormData)を使用するためにpolyfillが必要な場合。含めることができるミニバージョンがあります – Endless

答えて

2

私はそれを同期的に行うことはできないと思います。ここでは非同期的にそれを行う方法です:

var SmFaq = {}; 
 

 
SmFaq.DataForm = function(f, callback) { 
 
    var name = f.querySelector('#created_by'), 
 
    file = f.querySelector('#file'), 
 
    data = '', 
 
    reader = new FileReader(); 
 

 
    reader.addEventListener('loadend', function() { 
 
    console.log('Here are binary datas !'); 
 
    data += reader.result; 
 

 
    callback(data); 
 
    }); 
 

 
    data += 'Created by '; 
 
    data += name.value; 
 
    data += '\n'; 
 

 
    if (file.files[0]) { 
 
    data += file.files[0].name; 
 
    data += '\n'; 
 
    data += ' ... '; 
 
    data += '\n'; 
 

 
    console.log('Waiting for binary datas...'); 
 
    reader.readAsBinaryString(file.files[0]); 
 
    } else { 
 
    callback(data); 
 
    } 
 
} 
 

 
function handleData(data) { 
 
    // Do whatever you want to do with data 
 
    console.log(data); 
 
} 
 

 
document.getElementById('myForm').addEventListener('submit', function(e) { 
 
    e.preventDefault(); 
 
    SmFaq.DataForm(this, handleData); 
 
});
<form id="myForm"> 
 
    <input type="text" id="created_by" placeholder="Who Am I ?" /><br /> 
 
    <input type="file" id="file" /><br /> 
 
    <input type="submit" value="Submit" /> 
 
</form>

変更DataFormがそれにコールバックを追加し、すべてのあなた件のデータを持っているときcallback関数を呼び出すために呼び出される方法。私の例では、コールバック関数handleDataの中のそれらのデータを処理します。

関連する問題