首頁 > web前端 > js教程 > promsie.all和promise順序執行詳解

promsie.all和promise順序執行詳解

小云云
發布: 2018-01-20 11:50:21
原創
3523 人瀏覽過

本文主要介紹了微信小程式promsie.all和promise順序執行的相關資料,希望透過本文能幫助到大家,需要的朋友可以參考下,希望能幫助到大家。

微信小程式promsie.all和promise順序執行

一、前言

最近在做小程式的開發,碰到的一個需求就是表單提交,提交的表單包含有圖片,微信這邊的做法是先上傳圖片,後台把圖片名稱和地址回傳給你,然後你把圖片資訊插入到表單的對應位置再提交表單,這裡就涉及到如何上傳完圖片的請求再上傳表單,而且微信小程式裡面如果圖片是多個的話,也只能一張張上傳。簡單來說就是上傳完圖片(多個請求),拿到回傳值,再上傳表單,該如何做?

二、Promise.all和Promise.race

#先介紹Promise.all和Promise.race方法的不同點Promise.all(iterable)方法指當所有在可迭代參數中的promises 已完成,或第一個傳遞的promise(指reject)失敗時,傳回promise。 iterable為可迭代對象,但一般為數組。傳回值也是一個Promise物件。

需要明確的幾點,Promise.all是並發執行的同時運行多個Promise對象,而且返回的Promise對象的參數是一個數組,數組中的各項也是可迭代對象執行的順序回傳。

Promise.race(iterable) 方法傳回一個新的promise,參數iterable中只要有一個promise物件」完成(resolve)」或」失敗(reject)”,新的promise就會立刻」完成( resolve)”或”失敗(reject)”,並獲得先前那個promise物件的返回值或錯誤原因。所以只要iterable中有一個完成或失敗就立即回傳一個promise物件。根據race這個單字為賽跑也能得出,最先到達的立即返回一個promise物件。

根據上面的定義,我們所採用的Promise.all方法來完成我們的需求。


//存储promise对象的数组
let promiseArr = [];
//图片地址数组
let imageList = [];
//将图片地址的上传的promise对象加入到promiseArr
for (let i = 0; i < imageList.length; i++) {
  let promise = new Promise((resolve, reject) => {
    //微信图片上传
    wx.uploadFile({
      url: &#39;https://xxx.xxx.xxx/api/uploadImage&#39;,
      filePath: imageList[i],
      name: &#39;file&#39;,
      success: function(res) {
        //可以对res进行处理,然后resolve返回
        resolve(res);
      },
      fail: function (error) {
        reject(error);
      },
      complete: function (res) {
      },
    })
  });
  promiseArr.push(promise)
}
//Promise.all处理promiseArr数组中的每一个promise对象
Promise.all(promiseArr).then((result) => {
  //对返回的result数组进行处理
})
登入後複製

三、微信小程式的問題

在做微信小程式的圖片上傳功能,這邊只能先上傳圖片,然後將圖片名稱和位址以response回傳。

這裡面我們就是用了promise.all方法但是有一個問題就是,promise.all是並發執行的,但是微信小程式一次只能並發10個請求。

對於圖片上傳,可能需要一次上傳超過10張圖片,也就是一次並發超過10個請求,這樣的話微信就會報錯

「WAService.js:4 uploadFile :fail createUploadTask:fail exceed max upload connection count 10」。

四、順序Promise執行處理

因為Promise.all是同時執行多個promsie對象,所以對於這種並發的數量,小程式是有限制的,一次只能並發10個,所以如果想突破這種限制,可以進行順序執行每個Promise。

程式碼如下:


//顺序处理函数
function sequenceTasks(tasks) {
  //记录返回值
  function recordValue(results, value) {
    results.push(value);
    return results;
  }
  let pushValue = recordValue.bind(null, []);
  let promise = Promise.resolve();
  // 处理tasks数组中的每个函数对象
  for (let i = 0; i < tasks.length; i++) {
    let task = tasks[i];
    promise = promise.then(task).then(pushValue);
  }
  return promise;
}

//函数数组,每个函数的返回值是一个promise对象
let promiseFuncArr = [];
//图片地址数组
let imageList = [];
//将图片地址的上传的函数加入到promiseFuncArr数组中
for (let i = 0; i < imageList.length; i++) {
  let promiseTemp = function(){
    return new Promise((resolve, reject) => {
      //微信图片上传
      wx.uploadFile({
        url: &#39;https://xxx.xxx.xxx/api/uploadImage&#39;,
        filePath: imageList[i],
        name: &#39;file&#39;,
        success: function(res) {
          //可以对res进行处理,然后resolve返回
          resolve(res);
        },
        fail: function (error) {
          reject(error);
        },
        complete: function (res) {
        },
      })
    });
  };
  promiseFuncArr.push(promiseTemp)
}

sequenceTasks(promiseFuncArr).then((result) => {
  //对返回的result数组进行处理
});
登入後複製

1.這裡解釋一下sequenceTasks函數的作用

首先recordValue函數傳入兩個值,一個是results是傳回的數組,另一個是value,value是傳入的值,results.push(value);將每一個值push到results數組,然後再傳回results數組。


let pushValue = recordValue.bind(null, []);
登入後複製

pushValue也是函數對象,將recordValue bind到一個[ ]陣列中,第一個參數傳null代表,不改變函數this的指向,所以pushValue得到就是一個function (value)的函數,參數傳入value。


promise = promise.then(task).then(pushValue);
登入後複製

task是函數,函數返回promise對象,在我們這裡就是上傳圖片函數,每一張圖片上傳都建立一個函數,then(pushValue),pushValue是function (value)的函數,value代表的就是圖片上傳之後的回傳值,pushValue會回傳值push到result數組中,依序執行,依序加入result數組中,最後回傳。就可以得到一個物件數組,數組中就是依序執行傳回的結果。

2. sequenceTasks也裡面的for循環,也可以寫成如下的reduce方式:


function sequenceTasks(tasks) {
  //记录返回值
  function recordValue(results, value) {
    results.push(value);
    return results;
  }
  let pushValue = recordValue.bind(null, []);
  return tasks.reduce(function (promise, task) {
    return promise.then(task).then(pushValue);
  }, Promise.resolve());
}
登入後複製

相關推薦:

headjs實作網站並行載入但順序執行JS

#Java中類別的載入順序執行結果詳細介紹

JS的程式碼執行有哪些先後順序

#

以上是promsie.all和promise順序執行詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板