摘要:本文通過實踐從古至今對封裝的各種方式,來了解在中異步編程的實現細節和設計模式。傳值方式實現傳對象方式實現基于其他實現當前是第次等待感覺是到來之前的過渡方案異步流程控制庫中文文檔參考使用深入理解的中文文檔
本文通過實踐從古至今對XMLHttpRequest封裝的各種方式,來了解在es中異步編程的實現細節和設計模式。
回顧XMLHttpRequest原生寫法XMLHttpRequest -MDN
var xhr = new XMLHttpRequest() xhr.timeout = 2000 xhr.open("POST", "path/to/api") xhr.onload= function () {console.log(xhr.status,xhr.responseText)} xhr.setRequestHeader("Content-type","text/plain;charset=UTF-8") xhr.send("{"key":"value"}")常見封裝方法 1.回調函數
傳值方式實現
function request(method, url, done) { var xhr = new XMLHttpRequest() xhr.open(method, url) xhr.onload = function () { if (this.status >= 200 && this.status < 300) done(null, xhr.response) else done(xhr.response) } xhr.onerror = function () {done(xhr.response)} xhr.send() } //--- request("GET", "path/to/api", function (err, res) { if (err){console.error(err)} console.log(res) })
傳對象方式實現
function request(obj){ var xhr = new XMLHttpRequest() xhr.open(obj.method, obj.url) xhr.onload= function () { if (this.status >= 200 && this.status < 300) obj.success(xhr.response) else obj.fail(xhr.response) } xhr.onerror= function () {obj.fail(xhr.response)} for(let key in obj.header){xhr.setRequestHeader(key ,obj.header[key])} xhr.send(obj.data) } //--- request({ url: "path/to/api", data: {}, method:"GET", header: {"Content-type": "application/json"}, success(res) {console.log(res)}, fail(err) {console.error(err)} })2.Promise
使用 Promise - MDN
Promise 本質上是一個綁定了回調的對象,而不是將回調傳進函數內部。
傳值方式實現
function requestPromise(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() }) } // --- requestPromise("GET", "path/to/api") .then(function (res1) { return makeRequest("GET", res1.url) }) .then(function (res2) { console.log(res2) }) .catch(function (err) { console.error(err) });
傳對象方式實現
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); });3.fetch ,Request (基于promise)
fetch-MDN
fetch("path/to/api", {credentials: "include"}) .then(function(response) { if (response.status >= 400) { throw new Error("Bad response from server"); } return response.json(); }) .then(function(stories) { console.log(stories); });
Request-MDN
var myRequest = new Request( "path/to/api", { method: "GET", headers: {"Content-Type": "application/json"}, mode: "cors", cache: "default" } ) fetch(myRequest).then(function(response) { //... });4.async/await (ES7)
async function -MDN
await -MDN
async function f1() { var res = await requestPromise("GET", "path/to/api"); console.log(res) } f1();其他 sleep 實現 (async/await)
function sleep (time) { return new Promise(function (resolve, reject) {setTimeout(resolve, time)}) } var start = async function () { for (var i = 1; i <= 10; i++) { console.log(`當前是第${i}次等待..`); await sleep(1000); } }; start();co+Generator
感覺是 async/await 到來之前的過渡方案
const co=require("co") //let begin = new Date(); co(function* (){ let buyed = yield buySomething(); //console.log(buyed ,new Date() - begin); let cleaned = yield clean(); //console.log(cleaned ,new Date() - begin); let cook_and_wash = yield [cook(),wash()]; //console.log(cook_and_wash ,new Date() - begin); let eated = yield eat(); //console.log(eated,new Date() - begin); });異步流程控制庫
RxJS 中文文檔
參考
XMLHttpRequest -MDN
使用 Promise - MDN
How do I promisify native XHR? - starkoverflow
深入理解ES7的async/await
fetch-MDN
Request-MDN
async function -MDN
await -MDN
RxJS 中文文檔
Promises/A+
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/54706.html
摘要:本文通過實踐從古至今對封裝的各種方式,來了解在中異步編程的實現細節和設計模式。傳值方式實現傳對象方式實現基于其他實現當前是第次等待感覺是到來之前的過渡方案異步流程控制庫中文文檔參考使用深入理解的中文文檔 本文通過實踐從古至今對XMLHttpRequest封裝的各種方式,來了解在es中異步編程的實現細節和設計模式。 回顧XMLHttpRequest原生寫法 XMLHttpRequest ...
摘要:本文通過實踐從古至今對封裝的各種方式,來了解在中異步編程的實現細節和設計模式。傳值方式實現傳對象方式實現基于其他實現當前是第次等待感覺是到來之前的過渡方案異步流程控制庫中文文檔參考使用深入理解的中文文檔 本文通過實踐從古至今對XMLHttpRequest封裝的各種方式,來了解在es中異步編程的實現細節和設計模式。 回顧XMLHttpRequest原生寫法 XMLHttpRequest ...
摘要:異步編程一般用來調取接口拉數據。通過我描述的篇幅,就知道異步編程比同步編程麻煩許多。遠古時期,異步編程是通過回調函數來解決的。 半理解系列--Promise的進化史 學過js的都知道,程序有同步編程和異步編程之分,同步就好比流水線,一步一個腳印,做完上個任務才做下一個,異步編程好比客服,客服接了一個電話,收到了一個任務,然后把任務交給另外的人來處理,同時,繼續接聽下一個電話,等到另外的...
摘要:模塊化之前的污染,命名污染命名空間模式減少上變量數量,但仍不安全匿名閉包模式應用由模塊組成,采用模塊規范。要想讓模塊再次運行,必須清除緩存。中優先于模塊內的其他內容執行。與其對應的值是動態綁定關系,實時取到模塊內部的值。 模塊化之前的JavaScript //Global污染,命名污染 function foo(){} //命名空間 NameSpace模式 var Module= { ...
摘要:接下來介紹下異步編程六種方法。六生成器函數是提供的一種異步編程解決方案,語法行為與傳統函數完全不同,最大的特點就是可以控制函數的執行。參考文章前端面試之道異步編程的種方法你不知道的中卷函數的含義和用法替代的個理由 前言 我們知道Javascript語言的執行環境是單線程。也就是指一次只能完成一件任務。如果有多個任務,就必須排隊,前面一個任務完成,再執行后面一個任務。 這種模式雖然實現起...
閱讀 1303·2021-11-11 10:57
閱讀 3717·2021-09-07 10:10
閱讀 3442·2021-08-03 14:03
閱讀 3067·2019-08-30 13:45
閱讀 681·2019-08-29 11:19
閱讀 1038·2019-08-28 18:07
閱讀 3099·2019-08-26 13:55
閱讀 809·2019-08-26 12:17