OLPM项目实践(4)-- 优化(异步编程)

promise异步编程

在OLPM项目中,数据传输都是依靠API接口,所以在页面中存在大量的动态请求。这个时候一定会遇上异步编程的问题。

试想一下,如果所有的数据都是同步地获取,那用户就要等非常长的时间才能看到完整的页面。而采用异步编程的方法,就能够大大地减少请求的时间。

针对异步编程,网上有很多开源的库已经有实现这个功能。其中,有一个非常轻量而且功能足够使用的promise。传送门:https://github.com/stackp/promisejs

 

情景理解:

request方法实现一次ajax请求:

request = function(url, cb, eb) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            if ((xhr.status >=200 && xhr.status < 300) || xhr.status === 304) {
                cb(xhr.responseText);
            } else {
                eb(new Error({
                    message: xhr.status
                }));
            }
        }
    };
    xhr.open('get', url, true);
    xhr.send(null);
}

如果我们要请求三个接口,分别拿到三个数据后再进行统一的数据处理呢?串行的方法是这样的:

//并行逻辑串行执行
request('data1', function(data1) {
    request('data2', function(data2) {
        request('data3', function(data3) {
            console.log(data1, data2, data3);//处理全部数据

            alert('success');
        }, function(err) {
            console.error(err);
        });
    }, function(err) {
        console.error(err);
    });
}, function(err) {
    console.error(err);
});

但其实,我们得到三个数据后再进行下一步处理时,请求是不需要串行执行的,这样会增加了等待的时间。

promise机制就是解决这样一类问题的解决方案。

 

promise机制

一个promise代表了一个异步操作的最终结果,通过promise的then方法来注册回调函数去接收promise的最终结果值或者是promise不能完成的原因。

每个promise都有三个状态:pending(默认)、fulfilled(完成)、rejected(失败);默认状态可以转变为完成态或失败态,完成态与失败态之间无法相互转换,转变的过程是不可逆的,转变一旦完成promise对象就不能被修改。通过promise提供的then函数注册onFulfill(成功回调)、onReject(失败回调)、onProgres(进度回调)来与promise交互。

大部分前端框架中使用Deferred来改变promise的状态(resolve()、reject())。

promise机制

通过promise机制,我们的编程方式可以编程这样:

request = function(url) {
    var def = new Deferred();

    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            if ((xhr.status >=200 && xhr.status < 300) || xhr.status === 304) {
                def.resolve(xhr.responseText)
            } else {//简化ajax,没有提供错误回调
                def.reject(new Error({
                    message: xhr.status
                }));
            }
        }
    };
    xhr.open('get', url, true);
    xhr.send(null);

    return def.promise;
}

request('data1.json').then(function(data1) {
    console.log(data1);//处理data1
    return request('data2.json');
}).then(function(data2) {
    console.log(data2);//处理data2
    return request('data3.json');
}, function(err) {
    console.error(err);
}).then(function(data3) {
    console.log(data3);
    alert('success');
}, function(err) {
    console.error(err);
});

并行逻辑串行执行:

all(
    [request('data1.json'),
    request('data2.json'),
    request('data3.json')]
    ).then(
        function(results){
            console.log(results);// 处理data1,data2,data3
            alert('success');
    }, function(err) {
        console.error(err);
    });

 

posted @ 2015-07-07 22:59  Joy Ho  阅读(303)  评论(0编辑  收藏  举报