异步与Promise与axios

1.异步与Promise

众所周知JavaScript是一种单线程的语言,因此能像Java一样多线程运行,所以促使了JavaScript需要使用异步回调来完成一些逻辑。

JavaScript中最典型的异步就是ajax请求数据以及setTimeout setInterval两个定时方法,而在ES6中正式规范了Promise,主流浏览器现在也大多支持ES6,因此Promise也成了主流的异步解决方案。

Promise是一个构造函数,可以视为Date这样的函数来对待,就像new Date()以后可以得到一个可以操作的对象,当new了一个Promise出来以后,就可以对这个对象进行then和catch的操作,也就是回调后成功跟失败两种情况对应得方法。new Promise对象时候,入参是一个有回调的异步函数,最简单的例如setTimeout()。以下是代码解释

function fun(time, arr = undefined) {
    return new Promise((resolve, reject) =>
        setTimeout(() => {
            try {
                console.log(arr[0]);
                resolve('success');
            } catch (error) {
                reject(error);
            }
        }, time)
    );
}
let p1 = fun(1000, [1]),
    p2 = fun(2000);

//正确处理
p1.then(data => {
    console.log('p1:' + data);
}).catch(data => {
    console.warn('p1:' + data);
});

//错误处理
p2.then(data => {
    console.log('p2:' + data);
}).catch(data => {
    console.warn('p2:' + data);
});

 运行结果:

 p1与p2分别调用了Promise的then与catch操作,而且也仅仅调用一次,例如将 fun 方法中的setTimeOut改成setInterval,则得到得到以下输出结果:

异步与Promise与axios_第1张图片

所以我们可以使用Promise对ajax进行封装,以方便复用:

function getData(data) {
    function ajax(resolve, reject) {
        $.ajax({
            url: 'http://127.0.0.1:8088/url',
            type: 'GET',
            dataType: 'json',
            data: data,
            success: data => {
                resolve(data);
            },
            error: () => {
                reject('error');
            }
        });
    }
    return new Promise(ajax);
}
getData({})
    .then(data => {
        console.log(data);
    })
    .catch(data => {
        console.warn('错误' + data);
    });

2.Promise的简单实现

基于对Promise的使用与了解,Promise有以下的基本特点:

1)Promise是一个构造函数或者说是一个类

2)Promise的实例化时异步方法是马上执行的

3)Promise的的实例化对象有then与catch两个方法

4)then与catch方法入参为函数,该函数在异步方法回调时候调用then与catch的入参

以下为Promise的简单实现(肯定不严谨

function MyPromise(fn) {
    //实例化then与catch方法 覆盖原回调方法为自定义的方法
    this.then = thenFn => {
        // console.log(this.callFn)
        this.callFn.thenFn = thenFn;
        return this;
    };
    this.catch = catchFn => {
        this.callFn.catchFn = catchFn;
        return this;
    };

    //原回调方法
    this.callFn = {
        thenFn: () => {},
        catchFn: () => {}
    };

    //异步函数回调
    this.thenFn = data => {
        this.callFn.thenFn(data);
    };

    this.catchFn = data => {
        this.callFn.catchFn(data);
    };

    //执行异步函数
    fn(this.thenFn, this.catchFn);
}

使用:

//正确处理
fun(1000, [1])
    .then(data => {
        console.log('p1:' + data);
    })
    .catch(data => {
        console.warn('p1:' + data);
    });

//错误处理
fun(2000)
    .then(data => {
        console.log('p2:' + data);
    })
    .catch(data => {
        console.warn('p2:' + data);
    });

 输出:

与原生的Promise基本一致。 

3.axios与异步请求

前端请求数据如果是同步请求,例如使用 from 标签的action方法就是典型的同步请求,但是同步请求时,浏览器就会停止执行其他操作,等待同步请求返回后,再继续执行其他代码,这种方法适用的情况比较少,因为如果后台请求时间较长,浏览器也只能等待,因此普遍情况下,请求数据都会采用异步请求的方式,这样等待服务器返回数据的时候,浏览器还可以进行其他操作,等服务器做出应答数据返回后,再执行接下来的操作如渲染数据等。

在看到异步请求时,一般想到的就是ajax,ajax是非常典型异步请求,ajax其实就是对XMLHttpRequest进行了封装,因为在jQuery中有ajax的方法,ajax被广泛使用。随着前端技术的进步,MVVM框架的流行,ES6标准的推广,现在很多人开始使用axios 来进行异步请求。

axios的异步其实还是基于XHR的,也是创建XHR进行请求,但是axios是支持Promise的,体积更小,使用起来更符合ES6的规范,而且被尤雨溪推荐了一波,势头很猛。

axios的中文文档:https://www.kancloud.cn/yunye/axios/234845

4.axios与Promise

axios因为支持Promise而被广泛使用,以下是axios的基本用法:

let data = {'code':'00'}

//使用get方法获取数据
axios.get('http://127.0.0.1:8088/url', data).then(response=> {}).catch(error => {});

//或者post方法
data = qs.stringify(data);
axios.get('http://127.0.0.1:8088/url', data).then(response=> {}).catch(error => {});

其实ES6有原生的fetch方法异步请求并且支持Promise,但是因为fetch的一些问题例如无法设置超时时间,无法监听请求进度等问题,fetch无法像axios一样热门。而且axios有丰富的配置,与使用拦截器进行预处理可以解决很多问题,例如权限控制等。

例如添加响应拦截器:

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 预处理
    if(response.status === 200){
        return Promise.reject(response.data);
    }else{
        return Promise.reject({'status_code':-1});
    }
    
}, function (error) {
    // 错误处理
    return Promise.reject(error);
});

5.总结

Promise使得异步请求更加规范,使用起来更加便捷,使代码逻辑清晰,而axios因为支持Promise得到了广泛的应用风头无量。但是Promise使用起来也是有些复杂,函数套函数,不如普通的异步回调简单粗暴,对初次使用使用者的javaScript基础有一定要求。

你可能感兴趣的:(前端相关)