Passing (object.function) as a parameter
I'm building a simple drag and drop uploader using Promises however I get an Uncaught SyntaxError: Unexpected token .
when I try and pass a method (object.function) as the parameter for the promise's callback functions resolve/reject.
I'm looking to organize my promise callbacks as methods underneath the resolve
and reject
objects so in the case of upload it would be resolve.upload
and reject.upload
, and for example if I had a signin promise for say user authentication then it would be ie. resolve.signin
and reject.signin
.
The current promise pattern is to chain then(), catch(), reject(), resolve() this is a horrible programming pattern if your using sockets and chain 2+ async calls the code becomes hard to manage as you nest more and more anonymous functions also known as the pyramid of doom pattern, to avoid this pattern, I'm using another one that I've used countless times for async calls as I'm doing in the below code when I set async event listeners client.addEventListener(prop, callback.upload[prop]);
and handle them in a separate object callback.upload.event
.
In the same way I'm handling the callback response for async request, I am trying to implement for promises to avoid chaining/nesting 5-10 async request in so long unmanageable function, however passing a methods (object.function) for callback functions for the promises function(resolve.upload,reject.upload)
doesn't seem to work, however is I pass a global function (function) ie, resolve
or reject
it will work just fine, however this is not good since it will be cluttering up the global namespace and is why I'm trying to pass a 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>
You can't pass your own callbacks to the function passed to the Promise constructor. What you can do is register callbacks in the subsequent chain, eg:
var p = new Promise(executor.upload).then(resolve.upload, reject.upload);
However for this to be useful the execute.upload
function must actually invoke the passed resolve
and reject
parameters based on what the XMLHttpRequest
object does:
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);
}
It's the action of calling resolve()
or reject()
inside the Promise constructor's callback that ultimately results in the handlers registered with .then
being called.
In the "fatarrow" syntax:
(param1, param2) => { thing to be returned }
the names in the parens on the left side are the names local to the { thing to be returned }
part. In fact, other than a difference in "this", about all fatarrow amounts to is a syntactical shorthand. So these two function definitions are basically identical:
blah: ( alpha, bravo ) => alpha + ", " + bravo
function blah ( alpha, bravo ) { return alpha + ", " + bravo; }
You want:
upload: ( resfunc, rejfunc ) => { ...etc... }
and wherever you CALL upload is where you would go:
upload(resolve.upload, reject.upload)
I'm also not sure about your use of promises. It is my understanding that the callbacks are given to you for you to call. That is, something like this.
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==';
}
);
Then you can use something like:
promise.then ( function () { /* promise says it is done, do something */ } );
链接地址: http://www.djcxy.com/p/55502.html
上一篇: 在Promise中混淆错误并拒绝