2016-01-04 6 views
3

Я создаю простой загрузчик с перетаскиванием, используя Promises, однако я получаю Uncaught SyntaxError: Unexpected token . при попытке передать метод (object.function) в качестве параметра для функций обратного вызова обещания/отклонить.Передача (object.function) в качестве параметра

Я ищу, чтобы организовать свое обещание обратные вызовы как методы под resolve и reject объектов, так и в случае загрузки было бы resolve.upload и reject.upload, и, например, если бы я имел обещание входа в аккаунт для аутентификации пользователей скажем тогда было бы т.е. resolve.signin и reject.signin.

Текущий шаблон обещания заключается в цепочке then(), catch(), reject(), resolve(), это ужасный шаблон программирования, если использование сокетов и цепочек 2+ асинхронных вызовов кода становится сложным для управления, поскольку вы гнезда все больше и больше анонимных функций, также известный как pyramid of doom pattern, чтобы избежать этого шаблона, я использую еще один, который я использовал бесчисленное количество раз для асинхронных вызовов, как я делаю в приведенном ниже коде, когда я устанавливаю асинхронные прослушиватели событий client.addEventListener(prop, callback.upload[prop]); и обрабатывать их в отдельном объекте callback.upload.event.

Точно так же я обрабатываю ответ обратного вызова для запроса async, я пытаюсь реализовать для обещаний избегать привязки/вложенности 5-10 асинхронного запроса с такой неуправляемой функцией, однако передавая методы (object.function) для функций обратного вызова для обещаний function(resolve.upload,reject.upload), похоже, не работает, однако я передаю глобальную функцию (функцию), то есть resolve или reject он будет работать нормально, однако это не хорошо, поскольку это будет загромождать глобальное пространство имен и именно поэтому я пытаюсь передать object.method.

<!DOCTYPE html> 
<html> 
<head> 
    <link rel="stylesheet" href="styles/upload.css"> 
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css"> 
    <script> 
     //EVENT LISTENERS 
     var listen = { 
      drag: ['dragenter','dragover','drop','dragleave'], 
      async: ['readystatechange','loadstart','progress','abort','error','load','timeout','loadend'] 
     }; 
     //PROMISES 
     var executor = { 
      //THIS IS WHERE MY PROBLEM LIES 
      upload: function(resolve.upload,reject.upload){ 
       var data = new FormData(); 
       var client = new XMLHttpRequest(); 
       data.append('xls', executor.upload.files); 
       for(prop of listen.async){ 
        client.addEventListener(prop, callback.upload[prop]); 
       } 
       client.open("POST", "/core/upload.php"); 
       client.send(data); 
      } 
     }; 
     //PROMISES HANDLERS 
     var resolve = { 
      upload: function(value){ 
       console.log(value); 
      } 
     }; 
     var reject = { 
      upload: function(reason){ 
       console.log(reason); 
      } 
     }; 
     //USER HANDLERS 
     var handles = { 
      upload: { 
       dragenter: function(e){ 
        e.target.classList.remove('emboss'); 
       } 
       dragover: function(e){ 
        e.preventDefault(); 
       } 
       drop: function(e){ 
        e.preventDefault(); 
        executor.upload.files = e.dataTransfer.files[0]; 
        //CREATE PROMISE 
        var p = new Promise(executor.upload); 
        console.log(p); 
        //CHECK PROMISE STATUS, EVERY 3 SECS 
        setInterval(function(){ 
         console.log(p); 
        }, 3000); 
       } 
       dragleave: function(e){ 
        e.target.classList.add('emboss'); 
       } 
      } 
     }; 

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

     //INITIALIZATION 
     function init(){ 
      var dropbox = document.getElementById('dropbox'); 
      for(prop of listen.drag){ 
       dropbox.addEventListener(prop, handles.upload[prop]);} 
      }; 
     //CALL INIT 
     document.addEventListener('DOMContentLoaded', init); 
    </script> 
    </head> 
    <body> 
     <div id="dropbox" class="fa fa-file-excel-o fa-4x emboss"></div> 
    </body> 
</html> 
+0

Вам нужно определить обратные вызовы перед объектом-исполнителем? – IrkenInvader

+0

@IrkenInvader да, это первое, что я подумал, но я изменил его и все тот же ошибку –

+3

Это странно во многих отношениях, трудно понять, с чего начать. –

ответ

2

Вы не можете передать свои функции обратного вызова функции передается конструктору Promise. То, что вы можете сделать, это зарегистрировать обратные вызовы в последующей цепочке, например.:

var p = new Promise(executor.upload).then(resolve.upload, reject.upload); 

Однако для этого, чтобы быть полезной функция execute.upload должна фактически ссылаться на передаваемые resolve и reject параметры, основанные на том, что делает XMLHttpRequest объект:

executor.upload = (resolve, reject) => { 
    var client = new XMLHttpRequest(); 

    client.addEventListener('readystatechange', (e) => { 
     // call `resolve` or `reject` as appropriate 
    }); 

    // then register any more specific handlers 
    for (prop of listen.async){ 
     client.addEventListener(prop, callback.upload[prop]); 
    } 

    client.open("POST", "/core/upload.php"); 
    client.send(data); 
} 

Это действие вызова resolve() или reject()внутри обратного вызова конструктора Promise, что в конечном итоге приводит к обработке обработчиков, зарегистрированных с вызванным .then.

+0

hmmm Позвольте мне попробовать это. –

+0

Заметьте, что добавление этих обещаний к вашему коду не позволяет использовать какие-либо функции, которые еще не реализованы, используя ваш существующий крюк read readatechange. – Alnitak

+0

Я пробовал что-то подобное раньше, но это определенно шаг вперед и действительно близко! Я понимаю, что вам нужно вызвать resol/reject внутри, но есть способ вызвать его из объекта 'callback.upload.events' ...так что в основном, если ошибки асинхронного вызова затем запускаются методом 'callback.upload.error', и мы можем вызывать, тогда вызываем' reject() ', и если ошибок нет, то' callback.upload.load' будет срабатывать и 'resolve()' you знаешь что я имею ввиду. –

1

В синтаксисе «fatarrow»:

(param1, param2) => { thing to be returned } 

имена в круглые скобки на левой стороне имена местных к { thing to be returned } части. На самом деле, помимо разницы в «этом», о всех числах футов, это синтаксическая стенография. Таким образом, эти два определения функции в основном идентичны:

blah: (alpha, bravo) => alpha + ", " + bravo 
function blah (alpha, bravo) { return alpha + ", " + bravo; } 

Вы хотите:

upload: (resfunc, rejfunc) => { ...etc... } 

и где бы вы ни ЗВОНИТЕ загрузки, где вы бы:

upload(resolve.upload, reject.upload) 

Я также не уверен, о вашем использовании обещаний. Я понимаю, что обратные вызовы даются вам для звонка. То есть, что-то вроде этого.

var promise = new Promise(
    function(resolve, reject) { 
     img.onload = function() { 
      ctx.drawImage(img, 300, 100); 
      resolve();       // done, tell the promise 
     }; 
     img.src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw=='; 
    } 
); 

Затем вы можете использовать что-то вроде:

promise.then (function() { /* promise says it is done, do something */ }); 
+0

так что вы говорите '(разрешать, отклонять) => {вещи, которые нужно вернуть}', тогда в моих обработчиках async, т.е. 'callback.upload.load' в моем примере, вызовите' resolve.upload ('мой успех msg'). ' –

+0

Я понимаю, что ваше высказывание, но то, что я пытаюсь сделать, это организовать мои обратные вызовы как методы, т.е.' callback.upload.load'. а затем встроенные анонимные функции .onload', должен быть способ сделать это ... а также тот же шаблон для обработки решения и отклонения обратных вызовов ... –

+0

Если я понимаю это, я думаю, что вы хотите, чтобы функция 'executor.upload' возвращала функцию. Что-то вроде 'var f = function (разрешить, отклонить) {/ * ... делать все, что вам нужно, чтобы эта функция выполнялась, вызывая решимость и отклонение при необходимости * /}; return f; ' –