javascript - 将 JS 类转换为真正的类

标签 javascript class ecmascript-6

我发现在我的项目中,我很想通过实现一个真正的类(class)来改进它。

const Fetch = {};

function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
      return response;
  } else {
      const error = new Error(response.statusText);
      error.response = response;
      throw error;
  }
}

function parseJSON(response) {
    return response.json();
}

/**
* @function
* @name Fetch
*/
Fetch.Fetch = (src, options = {}) => {
  return window.fetch(src, options)
    .then(checkStatus);
}

/**
* @function
* @name FetchJSON
*/
Fetch.FetchJSON = (src, options = {}) => {
  return window.fetch(src, options)
    .then(checkStatus)
    .then(parseJSON);
}

/**
* @function
* @name GetJSON
*/
Fetch.GetJSON = (src, options = {}) => {
  options = Object.assign({}, options, {
    method: 'GET'
  });

  return Fetch.FetchJSON(src, options);
}

Fetch.GetApiJSON = (src, options = {}) => {
  options = Object.assign({}, options, {
    headers: {
      'some-info': 'your header'
    }
  });

  return Fetch.GetJSON(src, options);
}

module.exports = Fetch;

我知道这不是创建类的方式,我很乐意以这种方式转换它。但我对那些帮助者有点困惑。

您对这样的事情有何看法:

new Fetch(url, options).Fetch();
new Fetch(url, options).GetJSON();

这样我就可以使用 Promise。 简而言之,您认为最好的方法是什么?

最佳答案

一种选择是实现流畅的界面。通过示例进行演示可能是最简单的:

const req = new Fetch('http://example.com');

req.get().then(handleResponse);
// -> calls window.fetch('http://example.com', { method: 'GET' })

const req2 = req.headers({ 'Content-Type': 'application/csv' });

req2.get().then(handleResponse);
// -> calls window.fetch('http://example.com', {
//            headers: { 'Content-Type': 'application/csv' },
//            method: 'GET' })

req2.options({ mode: 'no-cors' }).get().then(handleReponse);
// -> calls window.fetch('http://example.com', {
//            headers: { 'Content-Type': 'application/csv' },
//            mode: 'no-cors',
//            method: 'GET' })

你明白了。每个方法调用都会返回一个新对象,我们可以使用该对象发出请求,或者调用其他方法来添加选项、 header 等(或两者)。

实现看起来像这样。我已经删除了 window.fetch,因此它只记录一些信息来向您显示结果。

function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    return response;
  } else {
    const error = new Error(response.statusText);
    error.response = response;
    throw error;
  }
}

function parseJSON(response) {
  return response.json();
}

function mergeOptions(...options) {
  const headers = Object.assign({}, ...options.map(({headers}) => headers));
  return Object.assign({}, ...options, { headers });
}

class Fetch {
  constructor(url, options={}) {
    this.url = url;
    this._options = options;
  }

  options(opts={}) {
    return new Fetch(this.url, mergeOptions(this._options, opts));
  }
  
  headers(headers={}) {
    return this.options({ headers });
  }

  fetch() {
    return window.fetch(this.url, this._options).then(checkStatus);
  }

  get() {
    return this.options({ method: 'GET' }).fetch();
  }
  
  getJSON() {
    return this.get().then(parseJSON);
  }
  
  getApiJSON() {
    return this.headers({ 'some-info': 'your header' }).getJSON();
  }
}

// Stub this out for demonstration
window.fetch = (...args) => {
  console.log('Called window.fetch with args', args);
  return Promise.resolve({
    status: 200,
    json() { return { hello: 'world' }; }
  });
}
function logResponse(res) { console.log('Got response', res); }

// Create a Fetch object
const req = new Fetch('http://example.com');

// Do a basic fetch
req.fetch().then(logResponse);

// Add some options to previous
const reqWithNoCache = req.options({ cache: 'no-cache' });

reqWithNoCache.fetch().then(logResponse);

// Add some headers to previous
const reqWithNoCacheAndHeader = reqWithNoCache.headers({ 'Accept-Language': 'en-US' });

reqWithNoCacheAndHeader.fetch().then(logResponse);

// Use convenience method with previous
reqWithNoCacheAndHeader.getApiJSON().then(logResponse);
.as-console-wrapper{min-height:100%}

关于javascript - 将 JS 类转换为真正的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43372901/

相关文章:

javascript - 如何使用 html、css、javascript 获取隐藏内容以显示在光标上?

java - 立即使用 jsonschema2pojo 生成的 Class 在代码中创建对象

c++ - 在 C++ 中将数组作为对象返回

C++:从函数更改类成员值

javascript - 通过迭代 JSON 对象创建新数组并仅获取其内部数组的 1 个

angular - ng serve --prod for ng-cli 结果在 UglifyJs SyntaxError : Unexpected token: name

javascript - 什么在移动设备上表现更好? Head.js 还是一个大的 js 文件?

javascript - 如何实际拦截 res.render

javascript - 如何在一行中默认导出命名导入?

javascript - 为每个数据集创建一个 Highchart