2017-04-12 6 views
0

私のプロジェクトでは、実際のクラスを実装することで、改善したいと思っています。JSクラスを実クラスに変換する

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(); 

私は、そのように約束を使用することができます。 簡単に言えば、それが最善の方法だと思いますか?

+1

今、あなたは、オブジェクトに添付メソッドの束を持っています。あなたが何かの複数のインスタンスを望んでいない/必要としないなら、そうすることは完全に容認できる方法です。複数のインスタンスを作成できるようにするには、コンストラクタを作成する必要があります。 –

答えて

1

1つの選択肢は、流暢なインターフェースを実装することです。例を挙げて説明するのが最も簡単な場合があります。

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' }) 

各メソッド呼び出しは、新しいオブジェクトを返します。新しいオブジェクトを要求したり、オプション、ヘッダーなど(またはその両方)を追加するための追加メソッドを呼び出します。

実装は次のようになります。私は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%}

関連する問題