Reputation: 113
I have this multiple function called checkForURLS
that calls another two functions that return callbacks, how can I add to the array once both callbacks have returned and then return the array as a callback? I'm working with pure JavaScript.
function checkForURLs(uniqueURL, customURL, callback) {
var errors = [];
checkForUniqueURL(uniqueURL, function(UniqueURLCallback) {
if (UniqueURLCallback===true) {
errors.push("This unique URL is already taken, please try another.");
}
});
if (customURL.length>0) {
checkForCustomURL(customURL, function(customURLCallback) {
if (customURLCallback===true) {
errors.push("This custom URL is already taken, please try another.");
}
});
}
if (errors.length>0) {
return callback(errors);
} else {
return callback(false);
}
}
Upvotes: 1
Views: 436
Reputation: 1
You can use Promise
constructor new Promise(function)
, Promise.all()
to perform task when checkForUniqueURL
and checkForCustomURL
callbacks have been called.
function callback(value) {
return value
}
function checkForUniqueURL(url, callback) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(callback(true))
}, Math.random() * 1500)
})
}
function checkForCustomURL(url, callback) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve(callback(true))
}, Math.random() * 1500)
})
}
function checkForURLs(uniqueURL, customURL, callback) {
var errors = [];
return Promise.all([
new Promise(function(resolve, reject) {
checkForUniqueURL(uniqueURL, function(UniqueURLCallback) {
if (UniqueURLCallback === true) {
errors.push("This unique URL is already taken, please try another.");
}
resolve()
})
})
, new Promise(function(resolve, reject) {
if (customURL.length > 0) {
checkForCustomURL(customURL, function(customURLCallback) {
if (customURLCallback === true) {
errors.push("This custom URL is already taken, please try another.");
}
resolve()
});
}
})
])
.then(function() {
console.log(errors);
if (errors.length > 0) {
return Promise.resolve(callback(errors));
} else {
return Promise.reject(callback(new Error("false")));
}
})
}
checkForURLs("abc", "def", callback)
.then(function(errs) {
console.log(errs);
})
.catch(function(err) {
console.log("err:", err.message)
})
Upvotes: 1
Reputation: 8406
This will work IFF your checkForUniqueURL
and checkForCustomURL
functions are synchronous. Here is an example of it working with synchronous functions...
https://jsfiddle.net/ojh5b1f8/
However, I'm going to assume, since its not working, that your functions are asynchronous. Here is an example of it not working with asynchronous functions...
https://jsfiddle.net/uzjbyrt7/
It doesn't work, because the checkForURLs
function returns before the callbacks are fired. The best solution in this case, is Promises. However, you will likely need to use a library to get promise support, since they are not yet implemented in all browsers. I recommend bluebird.js. Here is an example of it working with asynchronous functions and promises...
https://jsfiddle.net/ynxcu7t6/
Upvotes: 0
Reputation:
If all functions you use are synchronous and are implemented similar to the following, you code works perfectly well:
function checkForURLs(uniqueURL, customURL, callback) {
var errors = [];
checkForUniqueURL(uniqueURL, function(UniqueURLCallback) {
if (UniqueURLCallback===true) {
errors.push("This unique URL is already taken, please try another.");
}
});
if (customURL.length>0) {
checkForCustomURL(customURL, function(customURLCallback) {
if (customURLCallback===true) {
errors.push("This custom URL is already taken, please try another.");
}
});
}
if (errors.length>0) {
return callback(errors);
} else {
return callback(false);
}
}
// Just test-implement those two functions:
function checkForUniqueURL(url, callback) { callback(true); }
function checkForCustomURL(url, callback) { callback(true); }
errors = checkForURLs("test", "test2", function(errors) {
console.log(errors);
return "I have got some errors!";
});
console.log(errors);
If indeed your code has asynchronous parts, you would need to "wait" with the return callback()
until those are finished. Maybe by wrapping them in another callback?
Upvotes: 0