赞
踩
AJAX ( Asynchronous JavaScript and XML ) 异步的 JS 和 XML,通过 AJAX 可以在浏览器中向服务器发送异步请求,核心是XMLHttpRequest。
初始化 XMLHttpRequest 对象 : 视不同浏览器创建 XMLHttpRequest 对象
打开与服务器的连接 : 使用 open() 方法开启连接
设置监听 XMLHttpRequest 状态改变的事件处理函数。可以在 onreadystatechange 之后直接书写函数,也可以单独书写函数, 然后在这里指定函数名即可。
设置请求报头。一般要设置跟当前请求有关的报头, 比如编码等。使用 setRequestHeader() 方法设定
发送请求。向服务器发请求,如果是 POST 请求, 可以发送参数, 否则发送 null 即可。
// AJAX基础步骤 // 1. 创建 xhrHttpRequest 对象 let xhr; if (window.xhrRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xhr = new xhrHttpRequest(); } else { // code for IE6, IE5 xhr = new ActiveXObject("Microsoft.xhr"); } // 设置JSON格式自动转换 xhr.responseType='json'; // 2. 设置请求方法和url // GET请求 xhr.open("GET", "http://127.0.0.1:3300/server?name=zs&password=123", true); // POST请求 // xhr.open('POST','http://127.0.0.1:3300/server') // xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded') // xhr.send(param) post请求参数放在 send 方法中 // 3. 发送 xhr.send(); // 4.事件绑定 处理服务端返回的结果 xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status >= 200 && xhr.status < 300) { // 手动转换 JSON 数据转为JS对象 JSON.parse(xhr.response) console.log(xhr.status); // 状态码 console.log(xhr.statusText); // 状态字符串 console.log(xhr.getAllResponseHeaders()); // 所有响应头 console.log(xhr.response); // 响应体 } } };
// 引入express模块 const express = require('express') // 创建应用对象 const app = express() const port = 3000 // 创建路由规则 // req 对请求报文的封装 // res 对响应报文的封装 app.get('/', (req, res) => { // JSON格式 JSON.stringify(data) res.send('Hello World!') }) // 如果参数值中有中文,比如张三丰,则用encodeURI对中文进行编码 data = "username="+encodeURI("张三丰")+"&password=2016"; // app.post("/", function (req, res) { // res.send("POST request to the homepage"); // }); // app.all("/secret", function (req, res, next) { // 设置响应头,允许跨域 response.setHeader('Access-Control-Allow-Origin','*'); // 允许任何类型的请求头 response.setHeader('Access-Control-Allow-Headers','*') // console.log("Accessing the secret section ..."); // next(); // pass control to the next handler // }); // 监听端口启动服务 app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) })
修改服务器代码后,自动重启的一个工具,nodemon server.js
// 解决 IE 缓存
xhr.open("GET",'http://127.0.0.1:3300/ie?t='+Date.now())
// 超时设置 2s
xhr.timeout=2000;
// 超时回调
xhe.ontimeout = function(){}
// 服务器设置定时器
// 网络异常回调
xhr.onerror = function(){}
// 停止发送当前请求
xhr.abort()
let x =null; let isSending = false; // 是否正在发送AJAX请求 if(isSending){ x.abort(); //如果正在发送,则取消该请求,创建一个新的请求 } x= new XMLHTTPRequest(); isSending = true; xhr.open("GET", "http://127.0.0.1:3300/delay", true); x.send(); // 4.事件绑定 处理服务端返回的结果 x.onreadystatechange = function () { if (x.readyState == 4) { isSending = false; } };
function ajax(obj){ // 默认参数 let defaults = { type : 'get', data : {}, url : '#', dataType : 'text', async : true, success : function(data){console.log(data)} } // 处理形参,传递参数的时候就覆盖默认参数,不传递就使用默认参数 for(let key in obj){ defaults[key] = obj[key]; } // 1、创建XMLHttpRequest对象 let xhr = null; if(window.XMLHttpRequest){ xhr = new XMLHttpRequest(); }else{ xhr = new ActiveXObject('Microsoft.XMLHTTP'); } // 把对象形式的参数转化为字符串形式的参数 /* {username:'zhangsan','password':123} 转换为 username=zhangsan&password=123 */ let param = ''; for(let attr in defaults.data){ param += attr + '=' + defaults.data[attr] + '&'; } if(param){ param = param.substring(0,param.length - 1); } // 处理get请求参数并且处理中文乱码问题 if(defaults.type == 'get'){ defaults.url += '?' + encodeURI(param); } // 2、准备发送(设置发送的参数) xhr.open(defaults.type,defaults.url,defaults.async); // 处理post请求参数并且设置请求头信息(必须设置) let data = null; if(defaults.type == 'post'){ data = param; xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); } // 3、执行发送动作 xhr.send(data); // 处理同步请求,不会调用回调函数 if(!defaults.async){ if(defaults.dataType == 'json'){ return JSON.parse(xhr.responseText); }else{ return xhr.responseText; } } // 4、指定回调函数(处理服务器响应数据) xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if(xhr.status == 200){ let data = xhr.responseText; if(defaults.dataType == 'json'){ // data = eval("("+ data +")"); data = JSON.parse(data); } defaults.success(data); } } } }
$.get(url, [data], [callback], [type])
$.post(url, [data], [callback], [type])
$.ajax({ // url url: 'http://127.0.0.1:3300/jquery-server', // 参数 data: {a:1, b:2}, // 请求类型 type: 'GET', // 响应体结果类型 dataType: 'json' // 成功的回调 success: function(data){ console.log(data); }, // 超时时间 timeout: 2000, error: function(error){ console.log(error); }, // 头信息 headers: { c:300, d:400 } })
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
// 为给定 ID 的 user 创建请求 axios.get('/user?ID=12345') .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); // 上面的请求也可以这样做 axios.get('/user', { params: { ID: 12345 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
// 处理并发请求的助手函数 // axios.all(iterable) // axios.spread(callback) function getUserAccount() { return axios.get('/user/12345'); } function getUserPermissions() { return axios.get('/user/12345/permissions'); } axios.all([getUserAccount(), getUserPermissions()]) .then(axios.spread(function (acct, perms) { // 两个请求现在都执行完成 }));
// 发送 GET 请求(默认的方法) axios('/user/12345'); // 发送 POST 请求 axios({ method: 'post', url: '/user/12345', data: { firstName: 'Fred', lastName: 'Flintstone' } }); // 获取远端图片 axios({ method:'get', url:'http://bit.ly/2mTM3nY', responseType:'stream' }) .then(function(response) { response.data.pipe(fs.createWriteStream('ada_lovelace.jpg')) });
在使用别名方法时, url
、method
、data
这些属性都不必在配置中指定。
这些是创建请求时可以用的配置选项。只有 url
是必需的。如果没有指定 method
,请求将默认使用 get
方法。
{ // `url` 是用于请求的服务器 URL url: '/user', // `method` 是创建请求时使用的方法 method: 'get', // default // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。 // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL baseURL: 'https://some-domain.com/api/', // `transformRequest` 允许在向服务器发送前,修改请求数据 // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法 // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream transformRequest: [function (data, headers) { // 对 data 进行任意转换处理 return data; }], // `transformResponse` 在传递给 then/catch 前,允许修改响应数据 transformResponse: [function (data) { // 对 data 进行任意转换处理 return data; }], // `headers` 是即将被发送的自定义请求头 headers: {'X-Requested-With': 'XMLHttpRequest'}, // `params` 是即将与请求一起发送的 URL 参数 // 必须是一个无格式对象(plain object)或 URLSearchParams 对象 params: { ID: 12345 }, // `paramsSerializer` 是一个负责 `params` 序列化的函数 // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/) paramsSerializer: function(params) { return Qs.stringify(params, {arrayFormat: 'brackets'}) }, // `data` 是作为请求主体被发送的数据 // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH' // 在没有设置 `transformRequest` 时,必须是以下类型之一: // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams // - 浏览器专属:FormData, File, Blob // - Node 专属: Stream data: { firstName: 'Fred' }, // `timeout` 指定请求超时的毫秒数(0 表示无超时时间) // 如果请求话费了超过 `timeout` 的时间,请求将被中断 timeout: 1000, // `withCredentials` 表示跨域请求时是否需要使用凭证 withCredentials: false, // default // `adapter` 允许自定义处理请求,以使测试更轻松 // 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)). adapter: function (config) { /* ... */ }, // `auth` 表示应该使用 HTTP 基础验证,并提供凭据 // 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头 auth: { username: 'janedoe', password: 's00pers3cret' }, // `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream' responseType: 'json', // default // `responseEncoding` indicates encoding to use for decoding responses // Note: Ignored for `responseType` of 'stream' or client-side requests responseEncoding: 'utf8', // default // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称 xsrfCookieName: 'XSRF-TOKEN', // default // `xsrfHeaderName` is the name of the http header that carries the xsrf token value xsrfHeaderName: 'X-XSRF-TOKEN', // default // `onUploadProgress` 允许为上传处理进度事件 onUploadProgress: function (progressEvent) { // Do whatever you want with the native progress event }, // `onDownloadProgress` 允许为下载处理进度事件 onDownloadProgress: function (progressEvent) { // 对原生进度事件的处理 }, // `maxContentLength` 定义允许的响应内容的最大尺寸 maxContentLength: 2000, // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte validateStatus: function (status) { return status >= 200 && status < 300; // default }, // `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目 // 如果设置为0,将不会 follow 任何重定向 maxRedirects: 5, // default // `socketPath` defines a UNIX Socket to be used in node.js. // e.g. '/var/run/docker.sock' to send requests to the docker daemon. // Only either `socketPath` or `proxy` can be specified. // If both are specified, `socketPath` is used. socketPath: null, // default // `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项: // `keepAlive` 默认没有启用 httpAgent: new http.Agent({ keepAlive: true }), httpsAgent: new https.Agent({ keepAlive: true }), // 'proxy' 定义代理服务器的主机名称和端口 // `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据 // 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。 proxy: { host: '127.0.0.1', port: 9000, auth: { username: 'mikeymike', password: 'rapunz3l' } }, // `cancelToken` 指定用于取消请求的 cancel token // (查看后面的 Cancellation 这节了解更多) cancelToken: new CancelToken(function (cancel) { }) }
某个请求的响应包含以下信息
{ // `data` 由服务器提供的响应 data: {}, // `status` 来自服务器响应的 HTTP 状态码 status: 200, // `statusText` 来自服务器响应的 HTTP 状态信息 statusText: 'OK', // `headers` 服务器响应的头 headers: {}, // `config` 是为请求提供的配置信息 config: {}, // 'request' // `request` is the request that generated this response // It is the last ClientRequest instance in node.js (in redirects) // and an XMLHttpRequest instance the browser request: {} }
使用 then
时,你将接收下面这样的响应 :
axios.get('/user/12345')
.then(function(response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
});
在使用 catch
时,或传递 rejection callback 作为 then
的第二个参数时,响应可以通过 error
对象可被使用,正如在错误处理这一节所讲。
你可以指定将被用在各个请求的配置默认值
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
// Set config defaults when creating the instance
const instance = axios.create({
baseURL: 'https://api.example.com'
});
// Alter defaults after instance has been created
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;
配置会以一个优先顺序进行合并。这个顺序是:在 lib/defaults.js
找到的库的默认值,然后是实例的 defaults
属性,最后是请求的 config
参数。后者将优先于前者。这里是一个例子:
// 使用由库提供的配置的默认值来创建实例
// 此时超时配置的默认值是 `0`
var instance = axios.create();
// 覆写库的超时默认值
// 现在,在超时前,所有请求都会等待 2.5 秒
instance.defaults.timeout = 2500;
// 为已知需要花费很长时间的请求覆写超时设置
instance.get('/longRequest', {
timeout: 5000
});
可以使用自定义配置新建一个 axios 实例
axios.create([config])
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
在请求或响应被 then
或 catch
处理前拦截它们。
// 添加请求拦截器 axios.interceptors.request.use(function (config) { // 在发送请求之前做些什么 console.log("请求拦截器 成功"); return config; }, function (error) { // 对请求错误做些什么 console.log("请求拦截器 失败"); return Promise.reject(error); }); // 添加响应拦截器 axios.interceptors.response.use(function (response) { // 对响应数据做点什么 console.log("响应拦截器 成功"); return response; }, function (error) { // 对响应错误做点什么 console.log("响应拦截器 失败"); return Promise.reject(error); });
如果你想在稍后移除拦截器,可以这样:
const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);
可以为自定义 axios 实例添加拦截器
const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});
使用 cancel token 取消请求
Axios 的 cancel token API 基于cancelable promises proposal,它还处于第一阶段。
可以使用 CancelToken.source
工厂方法创建 cancel token,像这样:
const CancelToken = axios.CancelToken; const source = CancelToken.source(); axios.get('/user/12345', { cancelToken: source.token }).catch(function(thrown) { if (axios.isCancel(thrown)) { console.log('Request canceled', thrown.message); } else { // 处理错误 } }); axios.post('/user/12345', { name: 'new name' }, { cancelToken: source.token }) // 取消请求(message 参数是可选的) source.cancel('Operation canceled by the user.');
还可以通过传递一个 executor 函数到 CancelToken
的构造函数来创建 cancel token:
const CancelToken = axios.CancelToken;
let cancel;
axios.get('/user/12345', {
cancelToken: new CancelToken(function executor(c) {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
})
// cancelToken: new axios.CancelToken(function (c) {
// cancel = c;
})
});
// cancel the request
cancel();
注意: 可以使用同一个 cancel token 取消多个请求
fetch("http://example.com/movies.json", {
// 请求方法
method: "POST",
headers: {
name: "zs",
},
body: "username=admin&password=admin",
})
.then(function (response) {
return response.json();
})
.then(function (myJson) {
console.log(myJson);
});
同源策略(Same-Origin Policy)最早由 Netscape 公司提出,是浏览器的一种安全策略。
同源: 协议、域名、端口号 必须完全相同, 违背同源策略就是跨域。
JSONP ( JSON with Padding ),是一个非官方的跨域解决方案,只支持 get 请求。
JSONP 利用 script 标签的跨域能力来发送请求的。
JSONP :
// 1. 动态的创建一个 script 标签 let script = document.createElement("script"); // 2. 设置 script 的 src,设置回调函数 script.src = "http://localhost:3000/testAJAX?callback=abc"; function abc(data) { alert(data.name); }; // 3. 将 script 添加到 body 中 document.body.appendChild(script); // 4. 服务器中路由的处理 router.get("/testAJAX" , function (req , res) { console.log("收到请求"); let callback = req.query.callback; let obj = { name:"孙悟空", age:18 } res.send(callback+"("+JSON.stringify(obj)+")"); // res.end(`callback(${JSON.stringify(obj)})`) });
<script src="http://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script> <!-- 动态创建script标签 --> <script> function hello(data) { console.log(data) } let script = document.createElement('script'); script.src = 'https://www.baidu.com/jquery-server?callback=?' let body = document.getElementsByTagName('body')[0] body.appendChild(script) </script> <script type="text/javascript"> $.getJSON("http://127.0.0.1:3300/jquery-server?callback=?", function(data) { console.log(data) }); </script>
function ajax(obj){ // jsonp仅仅支持get请求 var defaults = { url : '#', dataType : 'jsonp', jsonp : 'callback', data : {}, success:function(data){console.log(data);} } for(var key in obj){ defaults[key] = obj[key]; } // 这里是默认的回调函数名称 // expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), var cbName = 'jQuery' + ('1.11.1' + Math.random()).replace(/\D/g,"") + '_' + (new Date().getTime()); if(defaults.jsonpCallback){ cbName = defaults.jsonpCallback; } // 这里就是回调函数,调用方式:服务器响应内容来调用 // 向window对象中添加了一个方法,方法名称是变量cbName的值 window[cbName] = function(data){ defaults.success(data);//这里success的data是实参 } var param = ''; for(var attr in defaults.data){ param += attr + '=' + defaults.data[attr] + '&'; } if(param){ param = param.substring(0,param.length-1); param = '&' + param; } var script = document.createElement('script'); script.src = defaults.url + '?' + defaults.jsonp + '=' + cbName + param; var head = document.getElementsByTagName('head')[0]; head.appendChild(script); // abc({"username":"zhangsan","password":"123"}) }
CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方 案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持 get 和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应 以后就会对响应放行。
// 引入express模块 const express = require('express') const app = express() const port = 3000 app.get('/', (req, res) => { // JSON格式 JSON.stringify(data) res.send('Hello World!') }) // 如果参数值中有中文,比如张三丰,则用encodeURI对中文进行编码 data = "username="+encodeURI("张三丰")+"&password=2016"; // 设置响应头,允许跨域 response.setHeader('Access-Control-Allow-Origin','*'); // 允许任何类型的请求头 response.setHeader('Access-Control-Allow-Headers','*') // 设置请求方法 response.setHeader('Access-Control-Allow-Method','*') // 监听端口启动服务 app.listen(port, () => { console.log(`Example app listening at http://localhost:${port}`) })
语法上Promise是一个构造函数,内部封装异步操作并可以获取其成功或失败的结果,异步编程的一种解决方案,用来解决回调地狱(在回调函数外面处理接收的数据)。
Promise三种状态:
当promise状态发生改变,就会触发then()里的响应函数处理后续步骤。
Promise状态改变只有:
promise状态一经改变,不会再变。
const p = new Promise((resolve, reject) => { setTimeout(function () { resolve("数据!"); // pending --> fulfilled reject("error!"); // pending --> rejected }, 1000); }); // then方法和catch方法返回的结果都是promise对象,对象状态由回调函数的执行结果决定(PromiseStatus,PromiseValue) // 链式调用 p.then(res => { console.log(res); }).catch(err => { console.log(err); }) p.then( res => { console.log(res); }, err => { console.log(err); } );
Promise对象的值:
实例对象中的另一个属性【PromiseResult】
保存着对象 【成功/失败】的结果
resolve
reject
Promise方法:
resolve
reject
all 参数中Promise全部返回成功才成功,返回一个新的Promise
race 参数中第一个完成Promise的结果状态就是最终的状态,返回一个新的Promise
Promise异常穿透:
const fs = require('fs'); // const util = require('util'); // const readFileAsync = util.promisify(fs.readFile); const { promisify } = require('util'); const readFileAsync = promisify(fs.readFile); async function read() { const content = await readFileAsync('./test.js', 'utf-8'); return content; } read().then(v => { console.log(v); });
class Promise{ //构造方法 constructor(executor){ //添加属性 this.PromiseState = 'pending'; this.PromiseResult = null; //声明属性 this.callbacks = []; //保存实例对象的 this 的值 const self = this;// self _this that //resolve 函数 function resolve(data){ //判断状态 if(self.PromiseState !== 'pending') return; //1. 修改对象的状态 (promiseState) self.PromiseState = 'fulfilled';// resolved //2. 设置对象结果值 (promiseResult) self.PromiseResult = data; //调用成功的回调函数 setTimeout(() => { self.callbacks.forEach(item => { item.onResolved(data); }); }); } //reject 函数 function reject(data){ //判断状态 if(self.PromiseState !== 'pending') return; //1. 修改对象的状态 (promiseState) self.PromiseState = 'rejected';// //2. 设置对象结果值 (promiseResult) self.PromiseResult = data; //执行失败的回调 setTimeout(() => { self.callbacks.forEach(item => { item.onRejected(data); }); }); } try{ //同步调用『执行器函数』 executor(resolve, reject); }catch(e){ //修改 promise 对象状态为『失败』 reject(e); } } //then 方法封装 then(onResolved,onRejected){ const self = this; //判断回调函数参数 if(typeof onRejected !== 'function'){ onRejected = reason => { throw reason; } } if(typeof onResolved !== 'function'){ onResolved = value => value; //value => { return value}; } return new Promise((resolve, reject) => { //封装函数 function callback(type){ try{ //获取回调函数的执行结果 let result = type(self.PromiseResult); //判断 if(result instanceof Promise){ //如果是 Promise 类型的对象 result.then(v => { resolve(v); }, r=>{ reject(r); }) }else{ //结果的对象状态为『成功』 resolve(result); } }catch(e){ reject(e); } } //调用回调函数 PromiseState if(this.PromiseState === 'fulfilled'){ setTimeout(() => { callback(onResolved); }); } if(this.PromiseState === 'rejected'){ setTimeout(() => { callback(onRejected); }); } //判断 pending 状态 if(this.PromiseState === 'pending'){ //保存回调函数 this.callbacks.push({ onResolved: function(){ callback(onResolved); }, onRejected: function(){ callback(onRejected); } }); } }) } //catch 方法 catch(onRejected){ return this.then(undefined, onRejected); } //添加 resolve 方法 static resolve(value){ //返回promise对象 return new Promise((resolve, reject) => { if(value instanceof Promise){ value.then(v=>{ resolve(v); }, r=>{ reject(r); }) }else{ //状态设置为成功 resolve(value); } }); } //添加 reject 方法 static reject(reason){ return new Promise((resolve, reject)=>{ reject(reason); }); } //添加 all 方法 static all(promises){ //返回结果为promise对象 return new Promise((resolve, reject) => { //声明变量 let count = 0; let arr = []; //遍历 for(let i=0;i<promises.length;i++){ // promises[i].then(v => { //得知对象的状态是成功 //每个promise对象 都成功 count++; //将当前promise对象成功的结果 存入到数组中 arr[i] = v; //判断 if(count === promises.length){ //修改状态 resolve(arr); } }, r => { reject(r); }); } }); } //添加 race 方法 static race (promises){ return new Promise((resolve, reject) => { for(let i=0;i<promises.length;i++){ promises[i].then(v => { //修改返回对象的状态为 『成功』 resolve(v); },r=>{ //修改返回对象的状态为 『失败』 reject(r); }) } }); } }
/** * resource 1.html 2.html 3.html 文件内容 */ const fs = require('fs'); const util = require('util'); const mineReadFile = util.promisify(fs.readFile); //回调函数的方式 // fs.readFile('./resource/1.html', (err, data1) => { // if(err) throw err; // fs.readFile('./resource/2.html', (err, data2) => { // if(err) throw err; // fs.readFile('./resource/3.html', (err, data3) => { // if(err) throw err; // console.log(data1 + data2 + data3); // }); // }); // }); //async 与 await async function main(){ try{ //读取第一个文件的内容 let data1 = await mineReadFile('./resource/1x.html'); let data2 = await mineReadFile('./resource/2.html'); let data3 = await mineReadFile('./resource/3.html'); console.log(data1 + data2 + data3); }catch(e){ console.log(e.code); } } main();
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。