【问题标题】:async POST request using Promises使用 Promises 的异步 POST 请求
【发布时间】:2016-01-05 06:58:14
【问题描述】:

我正在构建一个简单的上传器,我之前已经构建了很多,但是没有一个使用 Promise,我遇到了一个问题。当我打电话给我的承诺时,我需要在下面的代码中绑定我的“上传的文件”来说一个表单数据对象又名data.append('xls', e.dataTransfer.files[0]),但是我无法再访问e 事件,所以我无法访问它并将其绑定到表单data 对象。

错误 - Uncaught (in promise) ReferenceError: e is not defined

<!DOCTYPE html>
<html>
<head>
    <script>
        //HELPER FUNCTION
        events = (o,type,handle)=>o.addEventListener(type,handle);
        listen = {
            drag: ['dragenter','dragover','drop','dragleave'],
            async: ['readystatechange','loadstart','progress','abort','error','load','timeout','loadend']
        };

        //PROMISES
        executor = {
            upload: (resolve,reject) =>{
                var data = new FormData();
                var client = new XMLHttpRequest();
                for(prop of listen.async){ events(client, prop, callback.upload[prop]);}

                //THIS IS WHERE MY PROBLEM LIES         
                data.append('xls', e.dataTransfer.files[0]);  
                client.addEventListener("load", callback.upload);
                client.open("POST", "/core/upload.php");
                client.send(data);
            }
        };

        //PROMISE CALLBACKS
        resolve = (value)=> console.log(value);
        reject = (reason)=> console.log(reason);    

        //EVENT HANDLES
        handles = {
            upload: {
                dragenter: (e)=> e.target.classList.remove('emboss'),
                dragover: (e)=> e.preventDefault(),
                drop: (e)=> {
                    e.preventDefault();
                    var p = new Promise(executor.upload);
                    console.log(p);
                },
                dragleave: (e)=> e.target.classList.add('emboss')   
            }
        };

        //ASYNC CALLBACKS
        callback = {
            upload: {
                readystatechange: (e)=> console.log(e.target.readyState),
                loadstart: (e)=> console.log('loadstart'),
                progress: (e)=> console.log('progress'),
                abort: (e)=> console.log('abort'),
                error: (e)=> console.log('error'),
                load: (e)=> console.log('load'),
                timeout: (e)=> console.log('timeout'),
                loadend: (e)=> console.log('loadend')
            }   
        };

        //INITIALIZATION
        init=()=>{
            var dropbox = document.getElementById('dropbox');
            for(prop of listen.drag){ events(dropbox, prop, handles.upload[prop]);}
        };  

        events(document,'DOMContentLoaded', init);
    </script>
</head>
<body>
    <div id='dropbox' class='fa fa-file-excel-o fa-4x emboss'></div>
</body>
</html>

【问题讨论】:

  • 语法错误。
  • 是否添加files作为executor的属性,引用为this.files而不是e.dataTransfer.files并在调用执行器之前设置它e.dataTransfer.files
  • @Traktor53 听起来不错,试试吧。
  • @Traktor53 不错!是的,它使用executor.upload.files 而不是this.files 工作,因为胖箭头语法不会在词汇上绑定thisdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/…,但如果我像data.append('xls', executor.upload.files) 那样称呼它,它工作正常,谢谢!
  • 如果你能把答案贴出来,我可以把它标记正确。

标签: javascript asynchronous promise form-data


【解决方案1】:

基本问题是将一个从事件对象获取的参数传递给 Promise 的执行器函数,注意执行器是由 Promise 构造函数同步调用的。

一种方法可能是创建一个执行器工厂函数,将参数保存在一个闭包中,但是在将文件参数值存储在执行器可以访问的位置时,这可能是矫枉过正。 设置上传函数对象的属性,例如:

executor = {
    upload: (resolve,reject) =>{
            var data = new FormData();
            var client = new XMLHttpRequest();
            for(prop of listen.async){ events(client, prop, callback.upload[prop]);}

            data.append('xls', executor.upload.files);
            ....  // etc 

并在创建promise之前设置参数,

. . .
executor.upload.files = e.dataTransfer.files[0]`;
var p = new Promise(executor.upload);
. . .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-23
    • 2019-07-21
    • 1970-01-01
    • 2017-01-11
    相关资源
    最近更新 更多