国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

詳解Angular.js的$q.defer()服務異步處理

2019-11-19 19:03:10
字體:
來源:轉載
供稿:網友

首先本文以個人目前項目的部分代碼為例說明為什么要用deferred。

function getBase64(img){//傳入圖片路徑,返回base64   function getBase64Image(img,width,height) {    var canvas = document.createElement("canvas");    canvas.width = width ? width : img.width;    canvas.height = height ? height : img.height;    var ctx = canvas.getContext("2d");    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);    var dataURL = canvas.toDataURL();    return dataURL;   }   var image = new Image();   image.crossOrigin = '';   image.src = img;   var base64='';   if(img){    image.onload =function (){     base64=getBase64Image(image);     console.log(base64);//位置一    }    console.log(base64);//位置二   }  }

就這段代碼,我想要在位置二處使用base64,然后結果呢?

兩處位置都打印了,位置一得到base64,ok,沒問題。當我在位置二想使用base64時,問題來了?onload隊列的問題,位置二總是無法正確的獲取到想要的base64,這個時候就可以考慮異步問題了。

我相信大家應該和我一樣,遇到這種情況第一反應應該是deferred讓函數異步執行。

那么,我講以上代碼使用deferred之后,問題完美解決!

function getBase64(img){//傳入圖片路徑,返回base64    function getBase64Image(img,width,height) {     var canvas = document.createElement("canvas");     canvas.width = width ? width : img.width;     canvas.height = height ? height : img.height;     var ctx = canvas.getContext("2d");     ctx.drawImage(img, 0, 0, canvas.width, canvas.height);     var dataURL = canvas.toDataURL();     return dataURL;    }    var image = new Image();    image.crossOrigin = '';    image.src = img;    var deferred=$q.defer();    if(img){     image.onload =function (){     deferred.resolve(getBase64Image(image));     }     return deferred.promise;    }    }getBase64('https://img.alicdn.com/bao/uploaded/TB1qimQIpXXXXXbXFXXSutbFXXX.jpg')    .then(function(base64){     var binaryblob = function (s, type) {//blob對象      var byteString = atob(s);      var array = [];      for (var i = 0; i < byteString.length; i++) {       array.push(byteString.charCodeAt(i));      }      return new Blob([new Int8Array(array)], {type: type});     };     var binaryPictureBlob = function (dataUrl, filterHead) {//上傳base64去頭      var s = filterHead ? dataUrl.replace(/^data:image//(png|jpeg|pjpeg|bmp|gif|x-png);base64,/, "") : dataUrl;      return binaryblob(s, "image/jpeg");     };     var pic=binaryPictureBlob(base64,true);//blob對象     //然后調接口將blob對象上傳    });

問題解決了,我又想到了分享!那么我將我的拙見寫出來,請不吝賜教!

什么是defer?

$q是Angular的一種內置服務,它可以使你異步地執行函數,并且當函數執行完成時或異常時它允許你使用函數的返回值或返回執行狀態通知等。

defer的意思是延遲,$q.defer() 可以創建一個deferred延遲對象實例,實例旨在暴露派生的Promise 實例,Promise就是一種對執行結果不確定的一種預先定義,如果成功,就xx;如果失敗,就xx,就像事先給出了一些承諾。

用法:

一個最完整的寫法:

var defer1 = $q.defer();  function fun() {   var deferred = $q.defer();   $timeout(function () {    deferred.notify("notify");    if (iWantResolve) {     deferred.resolve("resolved");    } else {     deferred.reject("reject");    }   }, 500);   return deferred.promise;  }  $q.when(fun())    .then(function(success){     console.log("success");     console.log(success);    },function(err){     console.log("error");     console.log(err);    },function(notify){     console.log("notify");     console.log(notify);    })    .catch(function(reson){     console.log("catch");     console.log(reson);    })    .finally(function(final){     console.log('finally');     console.log(final);    });

1、通過$q服務注冊一個延遲對象

var deferred=$q.defer();

2、成功解決(resolve)了其派生的promise。參數value將來會被用作successCallback(success){}函數的參數value。

 deferred.resolve(success)

3、未成功解決其派生的promise。參數reason被用來說明未成功的原因。此時deferred實例的promise對象將會捕獲一個任務未成功執行的錯誤,promise.catch(errorCallback(reason){...})

 deferred.reject(reason) 

4、更新promise的執行狀態通知

deferred.notify("notify");

5、對promise進行處理

 $q.when(fun())    .then(function(success){     console.log("success");     console.log(success);    },function(err){     console.log("error");     console.log(err);    },function(notify){     console.log("notify");     console.log(notify);    })    .catch(function(reson){     console.log("catch");     console.log(reson);    })    .finally(function(final){     console.log('finally');     console.log(final);    });

這里一般簡寫為:

fun().then(successCallback, errorCallback, notifyCallback);

注:

deferred的方法中的參數都返回給了promise與callback的參數都是一一對應的,如:

  deferred.resolve(success)的success對應successCallback(success)的success。

這里在探討下暫時很少用的$q.all().

$q.all()在多個promise必須執行成功后才能執行成功回調,傳遞值為數組或哈希值,數組中每個值為與Index對應的promise對象。

這個方法可以將每個promise里的某些重復代碼或者判斷,只需要在$q.all()的回調處理一次即可,簡化了代碼與工作量。

寫法為:

var iWantResolve = true;//沒有實際意思,測試運行resolve或reject  function promise1() {   return $q(function (resolve, reject) {    $timeout(function () {     if (iWantResolve) {      resolve("promise1 resolved");     } else {      reject("promise1 reject");     }    }, 1000)   })  }  promise1()    .then(function (s1) {//success callback     console.log(s1);    })    .catch(function (err1) {//error callback     console.log(err1);    });  function promise2() {   var deferred = $q.defer();   $timeout(function () {    deferred.notify("promise2 notify");    if (iWantResolve) {     deferred.resolve("promise2 resolved");    } else {     deferred.reject("promise2 reject");    }   }, 500);   return deferred.promise;  }  promise2()    .then(function (s2) {     console.log(s2);    }, function (err2) {     console.log(err2);    });  $q.all([promise1(), promise2()])    .then(function (dataArr) {     //promise都成功執行后的回調函數     console.log("$q.all: ", dataArr);    }, function (err) {     console.log("$q.all: ", err)    });

像這個例子,每個promise回調都打印了返回值,那么可以用$q.all()處理在其回調打印dataArr,則包含了所有promise返回值!

jquery和angular的deferred用法大致相同,但有兩處要注意的地方:

jquery:

defer=$.Deferred();defer.promise();

angular:

var deferred=$q.defer();deferred.promise;

總結

以上便是我對angular的$q、deferred、promise的一些淺顯的理解,希望對大家的學習或者能有所幫助,如果有疑問大家可以留言交流。望各位大神多多評論、指教……

最后附上:

jquery中文網的deferred介紹:

http://www.jquery123.com/category/deferred-object/

一位大神對jquery的deferred的總結!

阮一峰:http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 海兴县| 黄冈市| 集贤县| 廉江市| 常德市| 马龙县| 英超| 大厂| 江城| 同江市| 茌平县| 南漳县| 敦煌市| 天等县| 日照市| 南通市| 文化| 井研县| 金门县| 容城县| 耒阳市| 九龙城区| 玛曲县| 建平县| 潍坊市| 盐津县| 弥勒县| 荔波县| 阿鲁科尔沁旗| 黑龙江省| 盐亭县| 浦县| 三穗县| 蒙城县| 扶余县| 洛隆县| 嘉义县| 青岛市| 工布江达县| 资兴市| 镇宁|