ossjssdk非同步架構改造

景丹發表於2018-09-18

### 背景
隨著js的技術變革,es6/7的語法的慢慢普及,並且很多的sdk都開始對新的非同步進行支援,因此我們也在開始進行調研,總結目前sdk存在的問題:

  • oss js sdk目前的非同步api需要依賴第三方庫co
  • api的呼叫棧很不清晰,定位問題困難,只要是因為這個co庫
  • 對於then的非同步方式需要一個wrapper來處理
  • issue上反饋了很多使用者的訴求

### 結構變化

  • 所有的對外暴露的api方法 由之前的 function* 轉變為 async function
  • 需要使用 yeild 的地方均由 await 代替
  • 底層非同步全部統一使用Promise / async await形式
  • 修改了部分bucket相關的api方法引數, 詳情參考readme

### 改進點
#### 1.使呼叫棧變得清晰,方便問題的排查。
co呼叫棧
co呼叫棧.jpeg
可以看出: 呼叫棧非常不清晰,太多沒有用的 co 相關的呼叫棧。如果 n 個 generator 層層巢狀,就會出現 n 倍的 (anonymous)->onFullfiled->next->toPromise->co->Promise->(anonymous) 呼叫棧。如果你讀過 co 的原始碼可能知道,這是 co 將 generator 解包的過程。其實這個可以通過 yield generator -> yield* generator 來解決。
async呼叫棧
aysnc呼叫棧.jpeg
可以看出: asyncWrap 中呼叫了 B 函式,B 函式呼叫了 A 函式,A 函式中 resolve 了一個值。asyncWrap 中還呼叫了 stopProfiling 函式。

2.去除了co以及相關的依賴

  • 減少了包的大小, 降低了1~2M
  • 簡化了使用

3.迴歸原生實現方式,相容性更好

  • 完全按照js es6/7的標準進行的封裝
  • 大部分主流瀏覽器都已經支援

4.初始化client不再需要一個wrapper,直接進行初始化即可

### 使用方式
舉個最常用的上傳api使用例子,分片上傳

const oss = require(`ali-oss`);

const store = oss({
  accessKeyId: `your access key`,
  accessKeySecret: `your access secret`,
  bucket: `your bucket name`,
  region: `oss-cn-hangzhou`
});

//async function 進度回撥
async function asyncProgress(p, cpt, res) {
    console.log(p);
    console.log(cpt);
    console.log(res.headers[`x-oss-request-id`]);
}

// 第二個引數是File|Blob
store.multipartUpload(`object`, `local-file`, {
  progress: asyncProgress
}).then((result) => {
  console.log(result);
});

//function 進度回撥
function progress(p, cpt, res) {
    console.log(p);
    console.log(cpt);
    console.log(res.headers[`x-oss-request-id`]);
}

// 第二個引數是File|Blob
store.multipartUpload(`object`, `local-file`, {
  progress: progress
}).then((result) => {
  console.log(result);
});

還有其他相關api使用請參考我們的官方文件

### 寫在最後

  • 我們會持續跟進js的新技術,選擇適合我們的技術並應用到sdk中去。
  • 歡迎隨時到github中提issue反饋問題


相關文章