2019-6-21 解决异步的方式
1. callback
ajax异步请求
- //如何封装一个原生的ajax
- function ajax(options){
- var data = options.data || {}
- var url = options.url || ' '
- var method = options.method || 'get'
- var success = options.success
- var fail = options.fail
- var dataType = options.dataType || 'text'
- // 第一步
- var ajax = new XMLHttpReques()
- //由于post 和 get 请求的方式不一样 要区别开来
- //method 统一转换成小写形式
- method = method.toLowerCase()
- if(method === 'get'){
- var arr = []
- for (var key in data){
- var str = key + '=' + data[key];
- arr.push(str)
- }
- if(arr.length){
- url += arr.join('&')
- }
- // 第二步
- ajax.open(method,url,true)
- // 第三步
- ajax.send()
-
- }else{
- //post 请求
- // 需要设置请求报文
- ajax.open(method,url);
- ajax.setRequestHeader("Content-type","application/x-www-form-urlencoded");
- // 判断data send发送数据
- if (data) {
- // 如果有值 从send发送
- ajax.send(data);
- }else{
- // 木有值 直接发送即可
- ajax.send();
- }
- }
- // 第四步
- ajax.onreadystatechange = function () {
- if (ajax.readyState == 4 && ajax.status == 200 || ajax.status == 304) {
- var _data;
- switch(datatype){
- case "json":
- _data = JSON.parse(ajax.responseText); // 此处_data 就是你指定的数据类型
- break;
- case "text":
- _data = ajax.responseText;
- break;
- }
- success(_data);
- }else{
- fail(_data)
- }
- }
-
- }
-
总结 :success 和 fail 函数 都是 回调函数callback,通过callback把异步获取的数据请求出来
2. promise
使用回调函数当然可以很好的解决异步代码的问题,但是多层嵌套很容易使代码书写麻烦,维护麻烦
fs.readdir(source, function (err, files) {
if (err) {
console.log('Error finding files: ' + err)
} else {
files.forEach(function (filename, fileIndex) {
console.log(filename)
gm(source + filename).size(function (err, values) {
if (err) {
console.log('Error identifying file size: ' + err)
} else {
console.log(filename + ' : ' + values)
aspect = (values.width / values.height)
widths.forEach(function (width, widthIndex) {
height = Math.round(width / aspect)
console.log('resizing ' + filename + 'to ' + height + 'x' + height)
this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {
if (err) console.log('Error writing file: ' + err)
})
}.bind(this))
}
})
})
}
})
基于三点规则来解决回调地狱
避免函数多层嵌套
模块化(职责单一)
处理问题简单
如何用 promise 封装原生的ajax
Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法。
reject 和 resolve 也是一种回调 换句话来说就是用回调封装成一种promise 再解决回调多层的概念
- // 定义一个promise 函数
- class Promise {
- constructor(exepromise){
- // 初始化 state 状态
- this.state = 'pedding'
- this.sucValue = undefined
- this.errValue = undefined
- let resolve = (data) =>{
- if(this.state == 'pedding'){
- this.sucValue = data
- this.state = 'resolve'
- }
- }
- let reject = (err)=>{
- if(this.state == 'pedding'){
- this.state = 'reject'
- this.errValue = err
- }
- }
- try{
- exepromise(resolve,reject)
- }catch(err){
- reject(err)
- }
- }
- then(toResolve,toReject){
- if(this.state == 'resovle'){
- toResolve(this.sucValue)
- }
- if(this.state == 'reject'){
- toReject(this.errValue)
- }
-
- }
- }
-
- var p = new Promise(function(resolve, reject){
- //做一些异步操作
- setTimeout(function(){
- console.log('执行完成');
- resolve('随便什么数据');
- }, 2000);
- });
-
3. async/await
async/await 是对 Promise 的优化: async/await是基于Promise的,是进一步的一种优化,不过在写代码时,Promise本身的API出现得很少,很接近同步代码的写法;
同时也可以说是 async 函数是 Generator 的语法糖。
3.1 async 函数
function 函数前面加个 == async==