首頁  >  文章  >  微信小程式  >  小程式中如何優雅的捕捉非同步方法的異常

小程式中如何優雅的捕捉非同步方法的異常

青灯夜游
青灯夜游轉載
2021-12-22 10:07:262045瀏覽

原生小程式中如何優雅的捕捉非同步方法的異常?以下這篇文章為大家介紹一下小程式中優雅的使用async await非同步程式設計的方法,希望對大家有幫助!

小程式中如何優雅的捕捉非同步方法的異常

最近開始寫一個開源的雲端開發社群小程序,在寫的過程中慢慢的摸索了一些對於開發和測試的過程中又幫助的奇技淫巧。這篇文章講一下在 原生小程式中如何優雅的捕捉非同步方法的異常

傳統方法

在ES7之後,我們往往使用async await 語法來進行非同步編程,如果我們要捕捉異常的話一般有以下兩種方式

try catch

async func(){
     //do something
}
try {
    const res = await func()
} catch (error) {
    //handle error
}

首先是try catch 捕捉異常,使用try catch 確實可以很方便的去處理異常,也可以阻止後面方法的進行,但是在開發的過程中咱們常常不止一個非同步方法,大量使用try catch 不僅寫的不爽,也絕對算不上優雅。

Promise.catch()

async func(){
     //do something
}

const res = await func().catch(error=>{
    //handle error
})

Promise物件內部了try catch ,我們可以使用鍊式呼叫的方法來處理異常。相較於try catchPromise.catch() 寫起來當然是爽很多的,看著也比較優雅了。

但是當我們想要在捕捉到錯誤後停止方法的繼續執行,那麼Promise.catch() 就沒辦法做到了,如下例子

async func(){
     //do something
}

const res = await func().catch(error=>{
    // 即使return也无效
    return
})
// 如果有错误的话我就不执行了

優雅方式

await-to-js github連結

https://github.com/scopsy/await-to-js

await-to-js 這個函式庫應該很多人了解過了,它是一個非同步請求的包裝器,可以用來處理非同步請求的錯誤,根據我們上面的需求改造為使用await-to- js 的範例如下

import to from 'await-to-js';

async func(){
     //do something
}

const [err,res] = await to(func())
if(err){
    //handle error
    return
}
// 如果有错误的话我就不执行了

透過將我們的非同步方法作為to() 方法的參數,傳回值透過一個陣列解構取得,陣列第一個值為捕捉到的錯誤,第二個值為正常執行的回傳值。

await-to-js的實作原理也非常簡單,就是使用Promise.catch()取得到異常後再將結果傳回在一個陣列中,原始碼如下

export function to<T, U = Error> (
	promise: Promise<T>,
	errorExt?: object
  ): Promise<[U, undefined] | [null, T]> {
	return promise
	  .then<[null, T]>((data: T) => [null, data])
	  .catch<[U, undefined]>((err: U) => {
		if (errorExt) {
		  const parsedError = Object.assign({}, err, errorExt);
		  return [parsedError, undefined];
		}
  
		return [err, undefined];
	  });
  }
  
  export default to;

小程式中使用

在小程式中,我們使用npm套件並不方便,因此我們可以直接將原始碼拿出來單獨使用,再加以改造的話就可以優雅的進行非同步程式設計啦,我自己的改造方式如下。

// lib/awaitTo.js
module.exports = function to(promise, description="unknown") {
	const pages = getCurrentPages()
	const route = pages[pages.length - 1].route||&#39;unknown&#39;
	description = `[${route}]---[${description}]`
	console.time(description)
	return promise
		.then(function (data) {
			console.timeEnd(description)
			return [null, data];
		})
		.catch(function (err) {
			wx.showToast({
				title: &#39;请求失败&#39;,
				icon: "none"
			})
			return [err, undefined];
		});
}

我透過getCurrentPages() 的方式取得到非同步方法執行時對應的頁面路由,在將第二個參數改為自己對非同步方法的一個描述,每一次呼叫非同步方法的時候就會在控制台輸出執行時間。實際使用的例子如下:

const to = require("../../lib/awaitTo")
const [err, res] = await to(db.collection("post").add({
        data: form
}),"addPost")
if (err) {
        // 处理我的错误
        return
}
// 成功后执行的逻辑

控制台列印的執行時間輸出如下,列印格式是

#【路由頁面】---【方法描述】:執行時間

小程式中如何優雅的捕捉非同步方法的異常

當然我的封裝方式是針對我自己的程式碼,你也可以根據你的實際業務再進行改造,例如埋點的統一入口之類的,可以大幅提升開發效率!

總結

在使用雲端開發時,為了開發體驗不得不使用原生的語言去寫,相對閉塞的環境就使得很多web端的方法沒法使用,在近期的摸索中我也找到了許多提升原生小程式開發體驗的方式,之後將會陸續更新。

【相關學習推薦:小程式開發教學

以上是小程式中如何優雅的捕捉非同步方法的異常的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除