-
Notifications
You must be signed in to change notification settings - Fork 70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Promise version? #64
Comments
That'd be cool. It should be easy to wrap 🤔 |
Yes, I thought about wrapping it myself, but thought I would ask here before I started looking at it if it where planned. I think it would be great instead of wrapping it myself. :) My thought was to use it together with |
@orecus I think is a good idea. If you want to implement it go ahead and I can review it and help |
@impronunciable I'll try to take a look at it in the coming days and see what I can do. :) Some alternatives for some form of rate limiting: |
Sadly I havn't had time too look at the code to try to implement this nativly within MovieDB. I solved this by simply wrapping the calls with moviedb as promises and using |
Great, is there any code I can take a look at? |
Sure, here are a quick and dirty example from the code i have, it will be available in full once the application i'm writing is in a shape to be shared. :) You call const PromiseThrottle = require('promise-throttle');
const throttle = new PromiseThrottle({ requestsPerSecond: 4, promiseImplementation: Promise });
const mdb = require('moviedb')(tmdbAPIKey);
function internal_searchMovie(searchData) {
let query = internal_searchTerm(searchData);
return new Promise(function (resolve, reject){
mdb.searchMovie(query, function(error, searchResults){
if (error) {
return reject({error: error.response.body.errors[0], type: 'TMDB Error'});
} else {
return resolve(searchResults.results);
}
});
});
}
function searchMovie(data, respond) {
if (data.id != undefined) {
respond(null, data);
} else {
throttle.add(internal_searchMovie.bind(this, data))
.then((searchResults) => {
respond(null, searchResults);
})
.catch((error) => {
respond(null, {error: error});
});
}
} |
Here's a quick little wrapper that supports all API calls. // moviedbp.js
var MovieDB = require('moviedb');
var endpoints = require('moviedb/lib/endpoints.json');
var limits = require('limits.js');
// rate limiting
var queue = limits();
queue.within(1000, 4);
function MovieDBP(api_key, base_url) {
this.moviedb = MovieDB(api_key, base_url);
return this;
}
Object.keys(endpoints.methods).forEach(function(method) {
var met = endpoints.methods[method];
Object.keys(met).forEach(function(m) {
MovieDBP.prototype[method + m] = function(params) {
var self = this;
if (typeof params == "function") {
params = {};
}
return new Promise(function(resolve, reject) {
queue.push(function() {
self.moviedb[method + m](params, function(err, res) {
if (err) return reject(err);
resolve(res);
});
});
});
};
});
});
module.exports = function(api_key, base_url) {
return new MovieDBP(api_key, base_url);
}; const mdbp = require('moviedbp')('your api key');
mdbp.searchMovie({ query: 'Alien' })
.then((res) => { console.log(res); })
.catch((err) => { console.log(err); }); Maybe an option to switch between callbacks and Promises would be nice? It breaks chaining but that's something you could document. Something like: require('moviedb')({ api_key: 'your api key', promise: true }); The rate limiting in my snippet could be used for both. |
Promise wrap: const _mdb = require('moviedb')('your-key')
const mdb = (m, q) => new Promise((res, rej) => {
_mdb[m](q, (err, data) => err ? rej(err) : res(data))
})
mdb('searchMovie', {query: 'Alien'})
.then(console.log)
.catch(console.error) With limits: const _mdb = require('moviedb')('your-key')
const limits = require('limits.js')
const throttle = limits().within(1000, 3)
const mdb = (m, q) => new Promise((res, rej) => {
throttle.push(() => _mdb[m](q, (err, data) => err ? rej(err) : res(data)))
})
mdb('searchMovie', {query: 'The Martian', year: 2015})
.then(console.log)
.catch(console.error) |
Through "testing" I see you ended up implementing the method as proposed by @daviestar but you haven't updated the readme yet, might I recommend doing that as well as closing the issue so it's clear to people that promises are available? Also to add some code feedback to this general feedback, the promises method also allows for an async/await approach: const moviedb = require('moviedb')(auth.TheMovieDBV3ApiKey);
async run(msg, args) {
const tmdb = (m, q) => new Promise((res, rej) => {
moviedb[m](q, (err, data) => err ? rej(err) : res(data)); // eslint-disable-line no-confusing-arrow
}),
tmdbres = await tmdb('searchMovie', {
'query': args.name
});
if (tmdbres) {
return console.log(tmdbres);
}
return console.log('error');
} Edit: a full implementation of the code above can be seen here, which is for my Discord bot: https://gist.github.com/Favna/5951fe0760553e99c0db139794ee4228 |
@favna I don't think a promise implementation has made it to this repo yet, but as you've already done it's easy to wrap it. When using try {
const tmdbres = await tmdb('searchMovie', {...})
if (tmdbres) {
return console.log(tmdbres)
}
return console.log('no response')
} catch (err) {
return console.error(err)
} Using the promise wrapper above is great for one-off searches but if you intend to loop through a big list of movies and grab metadata, you should take a look at the slightly more complicated implementation here: #74 (comment) |
Love this library, but I was just wondering if there have been any thoughts about moving to promises for this?
The text was updated successfully, but these errors were encountered: