jquery和angular都有defer服务,我暂以angular为例谈谈我的理解,最后并附上jquery的阮一峰总结的defer。

  以我目前项目的部分代码为例说明为什么要用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

angular中的$q.defer()服务异步处理的更多相关文章

  1. promise和Angular中的 $q, defer

    在ES6语法中,新出了promise构造函数, 可用来生成promise实例. Promise对象: 代表了未来某个将要发生的事件(通常是一个异步操作).有了promise对象, 可以将异步操作以同步 ...

  2. 形象的讲解angular中的$q与promise(转)

    以下内容摘自http://www.ngnice.com/posts/126ee9cf6ddb68 promise不是angular首创的,作为一种编程模式,它出现在……1976年,比js还要古老得多. ...

  3. 原创:形象的讲解angular中的$q与promise

    promise不是angular首创的,作为一种编程模式,它出现在……1976年,比js还要古老得多.promise全称是 Futures and promises.具体的可以参见 http://en ...

  4. angular中的$q服务实例

    用于理解$q服务 参考:http://www.zouyesheng.com/angular.html#toc39 广义回调管理 和其它框架一样, ng 提供了广义的异步回调管理的机制. $http 服 ...

  5. Angular中的$q的形象解释及深入用法

    作者:寸志链接:https://zhuanlan.zhihu.com/p/19622332来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 早上,老爸说:“儿子,天气如何 ...

  6. angularjs中使用$q.defer

    方法method1和方法method2的区别,我还正在研究中...待添加 代码如下: <html ng-app="myApp"> <head> <ti ...

  7. Angular中怎样创建service服务来实现组件之间调用公共方法

    Angular组件之间不能互相调用方法,但是可以通过创建服务来实现公共方法的调用. 实现 创建服务命令 ng g service 服务路径/服务名 比如这里在app/services目录下创建stor ...

  8. angular中的$q服务

    $q的一共有四个api: 1.$q.when(value, successFn, errorFn, progressFn),返回值为一个promise对象 --value可以是一个任意数据,也可以是一 ...

  9. 浅谈Angular的 $q, defer, promise

    浅谈Angular的 $q, defer, promise 时间 2016-01-13 00:28:00  博客园-原创精华区 原文  http://www.cnblogs.com/big-snow/ ...

随机推荐

  1. GIT本地免密配置

    在C:\Users\计算机名    下面找到.gitconfig文件(如果没有请新建) 内容为: [user]    name = git用户名[user]    email = 邮箱   [cred ...

  2. IntelliJ添加Emacs编辑器

    Intellij只支持emacs as a external tool: https://www.jetbrains.com/help/idea/2016.2/tutorial-using-emacs ...

  3. js判断地址转向

    <script type="text/javascript"> if (navigator.userAgent.search(/iphone|ipod|ipad|And ...

  4. Java面试查漏补缺

    一.基础 1.&和&&的区别. [概述] &&只能用作逻辑与(and)运算符(具有短路功能):但是&可以作为逻辑与运算符(是“无条件与”,即没有短路的功 ...

  5. .Net 跨平台可移植类库正在进行

    [原文发表地址] Cross-Platform Portable Class Libraries with .NET are Happening [译文发表地址] .Net 跨平台可移植类库正在进行 ...

  6. APP漏洞扫描器之本地拒绝服务检测详解

    APP漏洞扫描器之本地拒绝服务检测详解 阿里聚安全的Android应用漏洞扫描器有一个检测项是本地拒绝服务漏洞的检测,采用的是静态分析加动态模糊测试的方法来检测,检测结果准确全面.本文将讲一下应用漏洞 ...

  7. 搭建 SVN 服务器

    安装.启动 SVN 服务器 在 Windows 下,可以使用以下命令将 SVN 服务注册到 windows 服务中去: sc create svnserver binPath= "drive ...

  8. 干货!表达式树解析"框架"(2)

    最新设计请移步 轻量级表达式树解析框架Faller http://www.cnblogs.com/blqw/p/Faller.html 为了过个好年,我还是赶快把这篇完成了吧 声明 本文内容需要有一定 ...

  9. Dynatree使用

    最近用到了Dynatree的树形结构,记录一下它的用法. 需求: 1.jquery.js 2.jquery-ui.custom.js 3.jquery.cookie.js 下载dynatree,放到资 ...

  10. Security1:Create Login

    Login 用于登陆SQL Server,语法是 -- Syntax for SQL Server CREATE LOGIN login_name { WITH <option_list1> ...