function jsonp(opts) {
  var prefix = opts.prefix || '__jp';

  // use the callback name that was passed if one was provided.
  // otherwise generate a unique name by incrementing our counter.
  var id = opts.name || prefix + count++;

  var timeout = opts.timeout || 60000;
  var cacheFlag = opts.cache || false;
  var enc = encodeURIComponent;
  var target = document.getElementsByTagName('script')[0] || document.head;
  var script;
  var timer;

  function cleanup() {
    if (script.parentNode) script.parentNode.removeChild(script);
    window[id] = noop;
    if (timer) clearTimeout(timer);
  }

  if (!opts.url) {
    throw new TypeError('url is null or not defined');
  }

  return new Promise(function(resolve, reject) {
    try {
      if (timeout) {
        timer = setTimeout(function() {
          cleanup();
          reject(new Error('Request timed out'));
        }, timeout);
      }

      window[id] = function(data) {
        cleanup();
        resolve(data);
      };

      // add params
      opts.url = buildURL(opts.url, opts.params, opts.paramsSerializer);
      // add callback
      opts.url +=
				(opts.url.indexOf('?') === -1 ? '?' : '&') +
				'callback=' +
				enc(id);
      // cache
      !cacheFlag && (opts.url += '&_=' + new Date().getTime());

      // create script
      script = document.createElement('script');
      script.src = opts.url;
      target.parentNode.insertBefore(script, target);
    } catch (e) {
      reject(e);
    }
  });
}
function jsonp(opts) {
  var prefix = opts.prefix || '__jp';

  
  
  var id = opts.name || prefix + count++;

  var timeout = opts.timeout || 60000;
  var cacheFlag = opts.cache || false;
  var enc = encodeURIComponent;
  var target = document.getElementsByTagName('script')[0] || document.head;
  var script;
  var timer;

  function cleanup() {
    if (script.parentNode) script.parentNode.removeChild(script);
    window[id] = noop;
    if (timer) clearTimeout(timer);
  }

  if (!opts.url) {
    throw new TypeError('url is null or not defined');
  }

  return new Promise(function(resolve, reject) {
    try {
      if (timeout) {
        timer = setTimeout(function() {
          cleanup();
          reject(new Error('Request timed out'));
        }, timeout);
      }

      window[id] = function(data) {
        cleanup();
        resolve(data);
      };

      
      opts.url = buildURL(opts.url, opts.params, opts.paramsSerializer);
      
      opts.url +=
				(opts.url.indexOf('?') === -1 ? '?' : '&') +
				'callback=' +
				enc(id);
      
      !cacheFlag && (opts.url += '&_=' + new Date().getTime());

      
      script = document.createElement('script');
      script.src = opts.url;
      target.parentNode.insertBefore(script, target);
    } catch (e) {
      reject(e);
    }
  });
}
function jsonp ( opts ) { var prefix = opts . prefix || '__jp' ; // use the callback name that was passed if one was provided. // otherwise generate a unique name by incrementing our counter. var id = opts . name || prefix + count ++ ; var timeout = opts . timeout || 60000 ; var cacheFlag = opts . cache || false ; var enc = encodeURIComponent ; var target = document . getElementsByTagName ( 'script' ) [ 0 ] || document . head ; var script ; var timer ; function cleanup ( ) { if ( script . parentNode ) script . parentNode . removeChild ( script ) ; window [ id ] = noop ; if ( timer ) clearTimeout ( timer ) ; } if ( ! opts . url ) { throw new TypeError ( 'url is null or not defined' ) ; } return new Promise ( function ( resolve , reject ) { try { if ( timeout ) { timer = setTimeout ( function ( ) { cleanup ( ) ; reject ( new Error ( 'Request timed out' ) ) ; } , timeout ) ; } window [ id ] = function ( data ) { cleanup ( ) ; resolve ( data ) ; } ; // add params opts . url = buildURL ( opts . url , opts . params , opts . paramsSerializer ) ; // add callback opts . url += ( opts . url . indexOf ( '?' ) === - 1 ? '?' : '&' ) + 'callback=' + enc ( id ) ; // cache ! cacheFlag && ( opts . url += '&_=' + new Date ( ) . getTime ( ) ) ; // create script script = document . createElement ( 'script' ) ; script . src = opts . url ; target . parentNode . insertBefore ( script , target ) ; } catch ( e ) { reject ( e ) ; } } ) ; }
JSONP handler

Options:
- param {String} qs parameter (`callback`)
- prefix {String} qs parameter (`__jp`)
- name {String} qs parameter (`prefix` + incr)
- timeout {Number} how long after a timeout error is emitted (`60000`)

@param {String} url
@param {Object|Function} optional options / callback
JSONP handler