前提
用webview 做app开发。中间遇到图片上传的问题,上传过程展示上传进度。
原来的思路是for 循环,创建异步上传。但是在做的过程中发现,会出现上传展示会出现 1/20 一下子就到了 7/20 然后 15/20 最后完成的现象。我觉得可能是 浏览器会一次性执行好几个请求,导致速度不均衡。所以我希望可以让一个请求完成,在进行另一个请求。
虽然有普通的方法可以实现这个过程。但是还是学到了一个新的方法来做这样的操作就是 承诺 promise
阮大神的解释
Promises对象
Promises对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口。
简单说,它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:
f1().then(f2);
f1要进行如下改写(这里使用的是jQuery的实现):
function f1(){
var dfd = $.Deferred();
setTimeout(function () {
// f1的任务代码
dfd.resolve();
}, 500);
return dfd.promise;
}
这样写的优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。
比如,指定多个回调函数:
f1().then(f2).then(f3);
再比如,指定发生错误时的回调函数:
f1().then(f2).fail(f3);
而且,它还有一个前面三种方法都没有的好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号
。这种方法的缺点就是编写和理解,都相对比较难。
代码 一张一张上传图片,一张加载完成,另一张开始加载。
function RenderSelectPhoto() {
renderDomImg().then(function() {
P.fileIndexImg++;
RenderSelectPhoto();
})
}
function renderDomImg() {
return new Promise(function(resolve, reject) {
var FilesLeng=getPropertyCount(P.Files);
var file=P.Files[P.fileIndexImg];
var image = document.createElement("img");
image.file = file;
var reader = new FileReader();
var ret = reader.readAsDataURL(file);
reader.onload = (function(aImg){
return function(e){
var img = new Image();
img.src = e.target.result;
var canvas = document.createElement("canvas");
canvas.width="300";
canvas.height="300";
ctx = canvas.getContext("2d");
img.onload= function(){
ctx.fillRect(0,0,300,300);
ctx.drawImage(img,0,0,300,300);
var _canvas = canvas.toDataURL("image/jpeg", 0.5);
$("#index" + photoclass).attr("src",_canvas);
setTimeout(function(){
resolve();//这里 开始下一次循环
},200)
}
};
}(image));
})
}
709

被折叠的 条评论
为什么被折叠?



