JavaScript如何保证本地XHR?

我想在我的前端应用程序中使用(本机)promise来执行XHR请求,但没有大型框架的所有功能。

我希望我的XHR返回的希望,但是,这并不工作(给我:Uncaught TypeError: Promise resolver undefined is

not a function

function makeXHRRequest (method, url, done) {

var xhr = new XMLHttpRequest();

xhr.open(method, url);

xhr.onload = function() { return new Promise().resolve(); };

xhr.onerror = function() { return new Promise().reject(); };

xhr.send();

}

makeXHRRequest('GET', 'http://example.com')

.then(function (datums) {

console.log(datums);

});

回答:

我假设您知道如何发出本机XHR请求

由于任何支持本机Promise的浏览器也将支持xhr.onload,因此我们可以跳过所有的onReadyStateChangetomfoolery。让我们退后一步,从使用回调的基本XHR请求函数开始:

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

});

欢呼!这不涉及任何非常复杂的事情(例如自定义标头或POST数据),但足以使我们前进。

回答:

我们可以这样构造一个承诺:

new Promise(function (resolve, reject) {

// Do some Async stuff

// call resolve if it succeeded

// reject if it failed

});

promise构造函数采用一个函数,该函数将传递两个参数(我们称它们为resolvereject)。您可以将它们视为回调,一个代表成功,另一个代表失败。示例很棒,让我们makeRequest使用此构造函数进行更新:

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

});

现在,我们可以利用promise的功能,将多个XHR调用链接起来(并且.catch将在每次调用中触发错误):

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

});

我们可以进一步改进它,添加POST /PUT参数和自定义标头。让我们使用带有签名的options对象而不是多个参数:

{

method: String,

url: String,

params: String | Object,

headers: Object

}

makeRequest 现在看起来像这样:

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

});

以上是 JavaScript如何保证本地XHR? 的全部内容, 来源链接: utcz.com/qa/401569.html

回到顶部