在微信小程式中使用 async await

2022-02-09 13:18:22 字數 4390 閱讀 1763

但是,以**的方式來寫程式,真的很傷,如果有乙個過程需要依次幹這些事情:

那麼,**大概會長這樣

wx.getstorage() => 

});}

});}

});}

});}

});

在 1.02.1904282 以及之後版本的開發工具中,增加了增強編譯的選項來增強 es6 轉 es5 的能力,啟用後會使用新的編譯邏輯以及提供額外的選項供開發者使用。

特性原有邏輯

增強編譯

async/await

不支援支援

(async () => );

console.log(p);

})();

在短暫的自動編譯執行之後,在偵錯程式介面的 console 頁籤中可以看到輸出:

hello async/await

雖然 async/await 得到了支援,但是還得把wx.abcd()封裝成 promise 風格才行。

node.js 在 util 模組中提供了promisify來把 node.js 風格的**轉換成 promise 風格,但顯然它不適用於 wx 風格。還是自己動手吧,也不用考慮太多,比如 wx 風格的非同步呼叫在形式上都是一致的,它們的特徵如下 :

所以,如果wx.abcd()改成了 promise 風格,通過 async/await 來編寫,大概應該是這個樣子

try  catch (err)  finally 

當然,catchfinally這兩個部分並不是必須,也就是說,不一定非得用try語句塊。但是,如果不用catch,會有乙個神坑存在,這個問題後面再說。現在首先要做的是改造。

promisify()就是乙個封裝函式,傳入原來的wx.abcd作為參加,返回乙個 promise 風格的新函式。**和解釋如下:

function promisify(fn) ),

// ^^^^^^^^ 這個新引數物件得有原本傳入的引數,

// ^^ 當然得相容沒有傳入引數的情況

success: res => resolve(res),

// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 注入 success **,resovle 它

fail: err => reject(err)

// ^^^^^^^^^^^^^^^^^^^^^^^^ 注入 fail **,reject 它

});});};}

舉例使用它:

const asynclogin = promisify(wx.login);  // 注意別寫成 wx.login(),為什麼,我不說

try catch (err) finally

不過老實說,把要用的非同步方法通過promisify乙個個處理,寫起來還是挺煩的,不如寫個工具函式把要用的方法一次性轉換出來。不過一查,wx下定義了不知道多少非同步方法,還是退而求其次,用到啥轉啥,不過可以批量轉,轉出來的結果還是封裝在乙個物件中。整個過程就是迭代處理,最後把每個處理結果聚焦在一起:

function toasync(names) 

)).filter(t => typeof t.member === "function")

.reduce((r, t) => , {});

}

這個toasync的用法大致是這樣的

const awx = toasync(["login", "request"]);

await awx.login();

await awx.request();

有些人可能更習慣單個引數傳入的方式,像這樣

const awx = toasync("login", "request");

那麼在toasync的定義中,引數改為...names就好,即

function toasync(...names) 

onlaunch: function()

});工具準備好了,**也大刀闊斧地進行了改造,看起來舒服多了,一執行卻報錯!為什麼???

先來看一段原來的**,是這樣的

wx.getstorage(

});

改造之後是這樣

const res = await awx.getstorage();  // <== runtime error

// do with res

awx.getstorage拋了個異常,原因是叫"blabal"的這個資料不存在。

為什麼原來沒有錯,現在卻報錯?

因為原來沒有定義fail**,所以錯誤被忽略了。但是promisify()fail**封裝成了reject(),所以awx.getstorage()返回的 promise 物件上,需要通過catch()來處理。我們沒有直接使用 promise 物件,而是用的await語法,所以reject()會以丟擲異常的形式體現出來。

用人話說,**得這樣改:

try );  // <== runtime error

// do with res

} catch (err)

傷心了不是?如果沒有傷心,你想想,每乙個呼叫都要用try ... catch ...**塊,還能不傷心嗎?

處理錯誤真的是個好習慣,但真的不是所有錯誤情況都需要處理。其實要忽略錯誤也很簡單,直接在每個 promise 形式的非同步調後面加句話就行,比如

const res = await awx

.getstorage()

.catch(() => {});

// ^^^^^^^^^^^^^^^^ 捕捉錯誤,但什麼也不幹

稍微解釋一下,在這裡awx.getstorage()返回乙個 promise 物件,對該物件呼叫.catch()會封裝 reject 的情況,同時它會返回乙個新的 promise 物件,這個物件才是await等待的 promise。

不過感覺.catch(() => {})寫起來怪怪的,那就封裝成乙個方法吧,這得改promise類的原形

promise.prototype.ignoreerror = function() );

};

這段**放在定義toasync()之前就好。

用起來也像那麼回事

const res = await awx

.getstorage()

.ignoreerror();

對於單個await非同步呼叫,如果不想寫try ... catch ...塊,還可以自己定義乙個iferror(fn)來處理錯誤的情況。但是如果需要批量處理錯誤,還是try ... catch ...用起順手:

try );

const settings = await awx.getsetting();

const = await awx.login();

const userinfo = await awx.getuserinfo();

} catch (err)

看,不需要對每個非同步呼叫定義fail**,乙個try ... catch ...處理所有可能產生的錯誤,這可不也是 async/await 的優勢

在微信小程式中使用wxs

官方文件 上述是直接在.wxml中使用,也可以放在公共方法裡面,方便在各個頁面中呼叫 例如在util資料夾中新增乙個 subutil.wxs,作用於段落超出17個字元自動擷取並顯示省略號 var sub function val if val.length 17 else module.export...

在微信小程式中使用vant

你們是不是也遇到了這種問題呢?好的,接下來就讓我來告訴大家真正的解決方案吧 首先,你需要在小程式根目錄下開啟命令視窗,依次 輸入以下命令 構建完成,會生成 miniprogram npm 資料夾 當在乙個頁面中呼叫vant的元件時,需要在對應的頁面json中新增如下配置 為 usingcompone...

微信小程式中使用watch

設定 setwatcher page let lastkey key key.length 1 假設key my.name 此時nowdata data my data.my,lastkey name let watchfun watch v handler watch v 相容帶handler和不...