Yerel bir XHR isteğini nasıl yapacağınızı bildiğinizi varsayıyorum ( burada ve burada fırçalayabilirsiniz )
Yana destekleri yerli sözler o herhangi bir tarayıcı da destekleyecek xhr.onload
, hepimiz atlayabilirsiniz onReadyStateChange
maskaralık. Bir adım geri gidelim ve geri çağrıları kullanarak temel bir XHR istek işleviyle başlayalım:
function makeRequest (method, url, done) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
done(null, xhr.response);
};
xhr.onerror = function () {
done(xhr.response);
};
xhr.send();
}
// And we'd call it as such:
makeRequest('GET', 'http://example.com', function (err, datums) {
if (err) { throw err; }
console.log(datums);
});
Yaşa! Bu çok karmaşık bir şey içermez (özel başlıklar veya POST verileri gibi) ancak bizi ileriye taşımak için yeterlidir.
Söz Verici
Biz böyle bir söz inşa edebiliriz:
new Promise(function (resolve, reject) {
// Do some Async stuff
// call resolve if it succeeded
// reject if it failed
});
Promise yapıcısı iki argümandan geçecek bir fonksiyon alır (diyelim ki onları resolve
ve reject
). Bunları biri başarı, diğeri başarısız olmak için geri aramalar olarak düşünebilirsiniz. Örnekler harika, makeRequest
bu kurucu ile güncelleyelim :
function makeRequest (method, url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(xhr.response);
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
}
// Example:
makeRequest('GET', 'http://example.com')
.then(function (datums) {
console.log(datums);
})
.catch(function (err) {
console.error('Augh, there was an error!', err.statusText);
});
Şimdi, birden fazla XHR çağrısını zincirleyerek sözlerin gücünden faydalanabiliriz (ve .catch
her iki çağrıda da bir hata için tetikleyeceğiz):
makeRequest('GET', 'http://example.com')
.then(function (datums) {
return makeRequest('GET', datums.url);
})
.then(function (moreDatums) {
console.log(moreDatums);
})
.catch(function (err) {
console.error('Augh, there was an error!', err.statusText);
});
Hem POST / PUT parametrelerini hem de özel başlıkları ekleyerek bunu daha da geliştirebiliriz. Şimdi imzayla birden fazla argüman yerine bir seçenekler nesnesi kullanalım:
{
method: String,
url: String,
params: String | Object,
headers: Object
}
makeRequest
şimdi şuna benzer:
function makeRequest (opts) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(opts.method, opts.url);
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
resolve(xhr.response);
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
if (opts.headers) {
Object.keys(opts.headers).forEach(function (key) {
xhr.setRequestHeader(key, opts.headers[key]);
});
}
var params = opts.params;
// We'll need to stringify if we've been given an object
// If we have a string, this is skipped.
if (params && typeof params === 'object') {
params = Object.keys(params).map(function (key) {
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
}
xhr.send(params);
});
}
// Headers and params are optional
makeRequest({
method: 'GET',
url: 'http://example.com'
})
.then(function (datums) {
return makeRequest({
method: 'POST',
url: datums.url,
params: {
score: 9001
},
headers: {
'X-Subliminal-Message': 'Upvote-this-answer'
}
});
})
.catch(function (err) {
console.error('Augh, there was an error!', err.statusText);
});
Daha kapsamlı bir yaklaşım bulunabilir MDN'yi .
Alternatif olarak, getirme API'sını ( çoklu doldurma ) kullanabilirsiniz.