小程序模板網(wǎng)

g微信小程序?qū)嵺`(一)用Promise 封裝API

發(fā)布時(shí)間:2017-12-27 11:03 所屬欄目:小程序開發(fā)教程

為什么使用Promise如果新接觸 Promise 的話,在網(wǎng)上能找到很多介紹 Promise 及其使用的文章(比如:ECMAScript 6 入門 / Promise 對(duì)象),這里就不贅述了,簡(jiǎn)而言之就是用來處理異步調(diào)用的一大利器。微信小程序的API ...

 
 
 

 

為什么使用Promise

如果新接觸 Promise 的話,在網(wǎng)上能找到很多介紹 Promise 及其使用的文章(比如:ECMAScript 6 入門 / Promise 對(duì)象),這里就不贅述了,簡(jiǎn)而言之就是用來處理異步調(diào)用的一大利器。

微信小程序的API都可以傳入函數(shù) success,fail 和 complete 來實(shí)現(xiàn)異步回調(diào)。

樣例一

// 顯示”載入中”,在一秒后消失
wx.showLoading({
    title: "載入中",
    success: function () {
        setTimeout(function () {
            wx.hideLoading()
        }, 1000)
    },
    fail: function(){},
    complete: function(){}
});

原生的 success,fail 和 complete 已能夠滿足基本的異步回調(diào)了,但是如果遇到多個(gè)連續(xù)的阻塞任務(wù),會(huì)造成多層嵌套(如樣例二所示),就很奔潰。

樣例二

// 顯示“保存中”,一秒后隱藏,半秒后顯示“載入中”,一秒后隱藏
wx.showLoading({
    title: "保存中",
    success: function () {
        setTimeout(function () {
            wx.hideLoading({
                success: function () {
                    setTimeout(function () {
                        wx.showLoading({
                            title: "載入中",
                            success: function () {
                                setTimeout(function () {
                                    wx.hideLoading()
                                },1000)
                            }
                        })
                    }, 500)
                }
            })
        }, 1000)
    }
})

上面的例子有七個(gè)阻塞任務(wù):顯示“保存中”,停頓一秒,隱藏,停頓半秒,顯示“載入中”,停頓一秒,隱藏。從直覺上來思考,這些任務(wù)應(yīng)該是以隊(duì)列的形式存在,一個(gè)完成了再開始下一個(gè),而非層層嵌套,這也是使用Promise的一大原因,可以鏈?zhǔn)秸{(diào)用。

上面的例子如果用Promise封裝之后的API來寫,看起來就非常直觀(樣例三)

樣例三

wsAPI.taskSequence()
    .then(() => wsAPI.showLoading({title: "保存中"}))
    .then(() => wsAPI.sleep(1000))
    .then(() => wsAPI.hideLoading())
    .then(() => wsAPI.sleep(500))
    .then(() => wsAPI.showLoading({title: "載入中"}))
    .then(() => wsAPI.sleep(1000))
    .then(() => wsAPI.hideLoading())
    .then(() => console.log("done"))

注: (A)=>{B} 是 ES6 的箭頭函數(shù),相當(dāng)于 function(A){B},箭頭函數(shù)不用顯式 return。

比如 () => 5 就會(huì) return 5

console.log((() => 5)()) // 5

封裝實(shí)現(xiàn)

wsAPI的源代碼實(shí)現(xiàn)如下:

let nullFn = () => {
};
function IllegalAPIException(name) {
    this.message = "No Such API [" + name + "]";
    this.name = 'IllegalAPIException';
}
let services = {
    sleep: (time) => {
        return new Promise(function (resolve, reject) {
            setTimeout(resolve, time);
        })
    },
    stop: () => {
        return new Promise(function (resolve, reject) {
        })
    },
    taskSequence: () => {
        return new Promise(function (resolve, reject) {
            resolve()
        })
    }
};
export let wsAPI = new Proxy(services, {
    get: function (target, property) {
        if (property in target) {
            return target[property];
        } else if (property in wx) {
            return (obj) => {
                return new Promise(function (resolve, reject) {
                    obj = obj || {};
                    obj.success = (...args) => {
                        resolve(...args)
                    };
                    obj.fail = (...args) => {
                        reject(...args);
                    };
                    obj.complete = nullFn;
                    wx[property](obj);
                });
            }
        } else {
            throw new IllegalAPIException(property);
        }

    }
});

wsAPI 用 Proxy(ECMAScript 6 入門 / Proxy)重新封裝了 wx 的所有API。并新增了 sleep ,stop 和 taskSequence。sleep 用于阻塞一段時(shí)間;taskSequence 是一個(gè)空的 Promise,讓代碼看起來更整齊美觀,可讀性更好(樣例四);stop 用于停止任務(wù)序列進(jìn)行下去(樣例五)

樣例四

// taskSequence
wsAPI.taskSequence()
    .then(() => wsAPI.showLoading({title: "保存中"}))
    .then(() => wsAPI.sleep(1000))
    .then(() => wsAPI.hideLoading())
    .then(() => wsAPI.sleep(500))
    .then(() => wsAPI.showLoading({title: "載入中"}))
    .then(() => wsAPI.sleep(1000))
    .then(() => wsAPI.hideLoading())
    .then(() => console.log("done"))

// 沒有 taskSequence,第一個(gè)promise就和下面的不對(duì)齊
wsAPI.showLoading({title: "保存中"})
    .then(() => wsAPI.sleep(1000))
    .then(() => wsAPI.hideLoading())
    .then(() => wsAPI.sleep(500))
    .then(() => wsAPI.showLoading({title: "載入中"}))
    .then(() => wsAPI.sleep(1000))
    .then(() => wsAPI.hideLoading())
    .then(() => console.log("done"))

樣例五

wsAPI.taskSequence()
    .then(() => wsAPI.showModal({title: "保存", content: "確定保存?"}))
    .then(res => {
        if (!res.confirm) {
            return wsAPI.stop();
        }
    })
    .then(() => console.log("to save"))
    .then(() => wsAPI.showLoading({title: "保存中"}))
    .then(() => wsAPI.sleep(1000))
    .then(() => wsAPI.hideLoading())
    .then(() => console.log("done"))


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉(cāng)庫(kù):starfork
本文地址:http://22321a.com/wxmini/doc/course/18272.html 復(fù)制鏈接 如需定制請(qǐng)聯(lián)系易優(yōu)客服咨詢:800182392 點(diǎn)擊咨詢
QQ在線咨詢