[4个基于]基于zepto使用Promise方法详细

时间:2020-08-22  来源:网页配色  阅读:

注意,由于在真实工作环境(wise aladdin)中不能使用真正原生的Promise,我们以zepto的Deferred代替,这里就是简单说下使用Deferred的场景

为什么要用promise

很多时候我们要写很多回调,以来完成不同方法之间的操作,然而回调的可读性、可维护性不好,导致会有过多的嵌套,比如想完成需求:发送不同的多个请求,当全部完成后才执行回调,普通的方法是循环结束当前请求时再进行下一个请求,然而使用Promise则很简单。
当我们使用ajax时,要考虑要错误的状态,但错误有很多种,比如网络错误是error方法,返回值有问题/不理想时又一种状态(还是会走success方法),过多的状态判断会使我们的代码不好维护,然后可以使用Promise来解决。

多个回调嵌套时可读性不强,我们可以使用Promise来颗粒化功能模块,使其更帅点。
其实理由比较简单,她可以使我们的异步代码操作更简单、维护性更好~

简单的说明

写个简单的Promise:(原生es6的),点这里看Promise的兼容性

jsvar p = new Promise(function (resolve, reject) {
    // resolve是让这个p成功
    // reject是让这个p失败
});

// then(成功回调, 失败回调);
p.then(function (data) {
    // 这里是成功时的回调,data是resolve时调用的参数
}, function (data) {
    // 这里是失败的回调,data是reject时调用的参数
});
然后考虑到兼容性,我们在wise aladdin里不能这么用,但我们可以依赖zepto的Deferred,点这里看Deferred的详细介绍,点这里看zepto Deferred的源码,那么现在来个例子吧:

jsfunction ajax() {
    var defer = $.Deferred();

    setTimeout(function () {
        // resolve是成功
        defer.resolve(true);

        // defer.reject();是失败
    }, 1000);

    // 返回promise对象,其实返回
    return defer.promise();
}

// then(成功回调, 失败回调);
ajax().then(function (data) {
    console.log(data);
    // 这里是成功时的回调,data是resolve时调用的参数
}, function (data) {
    console.error(data);
    // 这里是失败的回调,data是reject时调用的参数
});
真实场景

所有promise执行完成 - 并行执行

比如想加载10个异步请求,然后在10个请求结束后得到这10个的返回值,代码如:

jsvar promiseArray = [];

new Array(10).join(",").split(",").forEach(function (value, index) {
    var defer = $.Deferred();

    setTimeout(function () {
        defer.resolve(index);
    }, 1000);

    promiseArray.push(defer);
});

// $.when是执行所有promise的方法,并行执行
// $.when(p1, p2, p3, p4);我们这里使用apply模拟args
// $.when思路同原生Promise.all一致,但用法不同,返回参数也不同
$.when.apply($, promiseArray).then(function () {
    console.log(arguments);
});
其实就是$.when(p1, p2, p3, p4).then(function (p1返回值, p2返回值, p3返回值, p4返回值) {});我们这里使用apply模拟args,切记,如果只是一个promise,就没必要使用when

串行的promise

想加载完1,使用1的数据去加载2

jsvar p1 = function () {
    var defer = $.Deferred();
    setTimeout(function () {
        defer.resolve("我是p1");
    }, 500);
    return defer.promise();
};

var p2 = function (data) {
    var defer = $.Deferred();
    setTimeout(function () {
        console.log("p2里调用p2Data => "+ data);
        defer.resolve("我是p2");
    }, 500);
    return defer.promise();
};

p1().then(function (p1Data) {
    return p2(p1Data);
}).then(function (p2Data) {
    console.log(p2Data);
});
切记:promise的then支持链式调用,下一个then的参数是上一个then的返回值~,如果then返回的是Promise则后续的要等这个Promise执行成功~

封装数据层

在异步请求多的模板里,我们通常要使用很多$.ajax来调用伟大的后端数据,然而为了用户体验,我们又必须考虑到各种错误状态,如果说每个$.ajax都写一套逻辑验证显然是不帅的,然而promise使这个操作异常简单~

js/**
 * 获取数据
 *
 * @param  {Object} data 往后端发送的数据对象
 *
 * @return {Promise}      Promise
 */
var getData = function (data) {
    var defer = $.Deferred();

    // 这里可以合并一些默认的公用参数,可以使用data来进行覆盖
    data = $.extend({
        // 默认参数
    }, data || {});

    $.ajax({
        url: "",
        data: data,
        dataType: "jsonp",
        jsonp: "cb",
        success: function (res) {
            if (后端数据校验成功) {
                defer.resolve(res);
            }
            else {
                // 报错给promise
                defer.reject();
            }
        },
        error: defer.reject
    });

    return defer.promise();
};

// 使用调用主页数据
getData({
    action: "index"
}).then(function (data) {
    // 这里是数据校验成功,并且没有错的数据回调
}, function () {
    // 这里是出错了
});

// 使用调用列表数据
getData({
    action: "list"
}).then(function (data) {
    // 这里是数据校验成功,并且没有错的数据回调
}, function () {
    // 这里是出错了
});
其实还可以再优化,我们还要按需求考虑到是否有用户主动取消请求的状态,比如xhr.abort再配合error里的status状态可以更完美~
这样数据容错、error优化都一步搞定,调用起来也方便~

superframe中的应用

superframe的使用API

其中返回的:create,start,stop,destory,resume方法可以支持Promise类型了,赞。。。superframe是按生命周期走的,当x步的promise被resolve时才会走到x+1步,那么就看自己的应用场景了,比如当superframe被调起时可以:

先请求数据,当数据成功时显示superframe,如果数据500ms不成功则显示superframe并显示loading
先执行动画,再写入loading,再请求数据
动画+loading+数据并行触发,ajax失败则报error错误+重试
动画+数据并行,全部完成才动画显示
...
以上只是我个人举例(目前superframe推荐使用动画+数据并行),她们的实际显示状态也不一样,看自己需求,组装成体验好的方式,但要考虑的是手机网速不好的状态下加载数据慢、超时的状态。

具体wise aladdin中开发superframe,后续我再写个分享~

其实Promise远比这些要帅气的多。本文只是简单的结合应用场景介绍了下$.Dererred, $.when, then,像Promise的其他done, fail, always并没有说,个人推荐使用then,因为这个支持链式的返回Promise,done是不支持的,另外always也有应用场景。

[4个基于]基于zepto使用Promise方法详细

http://m.bbyears.com/wangyezhizuo/94075.html

推荐访问:
相关阅读 猜你喜欢
本类排行 本类最新