我发现在我的项目中,我希望通过实施真正的课程来改进它。
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();
我可以用这种方式使用承诺。 简而言之,您认为这是最好的方式?
答案 0 :(得分: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);
&#13;
.as-console-wrapper{min-height:100%}
&#13;