最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2016年11月06日 10:44:01   作者:webNick  
相信大家都知道jquery和angular都有defer服務(wù),這篇文章暫以angular為例談?wù)剛€(gè)人的理解,在文章的最后并附上jquery的阮一峰總結(jié)的defer。有需要的朋友們也可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧。

首先本文以個(gè)人目前項(xiàng)目的部分代碼為例說明為什么要用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,然后結(jié)果呢?

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

我相信大家應(yīng)該和我一樣,遇到這種情況第一反應(yīng)應(yīng)該是deferred讓函數(shù)異步執(zhí)行。

那么,我講以上代碼使用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對(duì)象
      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對(duì)象
     //然后調(diào)接口將blob對(duì)象上傳
    });

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

什么是defer?

$q是Angular的一種內(nèi)置服務(wù),它可以使你異步地執(zhí)行函數(shù),并且當(dāng)函數(shù)執(zhí)行完成時(shí)或異常時(shí)它允許你使用函數(shù)的返回值或返回執(zhí)行狀態(tài)通知等。

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

用法:

一個(gè)最完整的寫法:

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服務(wù)注冊一個(gè)延遲對(duì)象

var deferred=$q.defer();

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

 deferred.resolve(success)

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

 deferred.reject(reason) 

4、更新promise的執(zhí)行狀態(tài)通知

deferred.notify("notify");

5、對(duì)promise進(jìn)行處理

 $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的方法中的參數(shù)都返回給了promise與callback的參數(shù)都是一一對(duì)應(yīng)的,如:

  deferred.resolve(success)的success對(duì)應(yīng)successCallback(success)的success。

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

$q.all()在多個(gè)promise必須執(zhí)行成功后才能執(zhí)行成功回調(diào),傳遞值為數(shù)組或哈希值,數(shù)組中每個(gè)值為與Index對(duì)應(yīng)的promise對(duì)象。

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

寫法為:

var iWantResolve = true;//沒有實(shí)際意思,測試運(yùn)行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都成功執(zhí)行后的回調(diào)函數(shù)
     console.log("$q.all: ", dataArr);
    }, function (err) {
     console.log("$q.all: ", err)
    });

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

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

jquery:

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

angular:

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

總結(jié)

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

最后附上:

jquery中文網(wǎng)的deferred介紹:

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

一位大神對(duì)jquery的deferred的總結(jié)!

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

 

相關(guān)文章

最新評(píng)論

定安县| 岳阳市| 扶风县| 峨边| 高邮市| 长阳| 龙门县| 东明县| 遂宁市| 开原市| 石阡县| 伊吾县| 甘德县| 崇信县| 肃南| 若尔盖县| 龙岩市| 平定县| 奈曼旗| 宝丰县| 黄浦区| 石河子市| 甘泉县| 大冶市| 台州市| 布尔津县| 织金县| 谢通门县| 泾源县| 宁陵县| 萨嘎县| 三河市| 南汇区| 绥化市| 广昌县| 桂林市| 怀来县| 双鸭山市| 林西县| 林周县| 绵竹市|