Javascript 以同步方式运行异步方法
我有一个简单的for循环,它基本上检查图像是否存储在文件系统中,如果没有,则下载它并呈现UI:Javascript 以同步方式运行异步方法,javascript,for-loop,asynchronous,Javascript,For Loop,Asynchronous,我有一个简单的for循环,它基本上检查图像是否存储在文件系统中,如果没有,则下载它并呈现UI: for (var t = 0; t < toJSON.length; t++) { if (t < 3) { var view = Titanium.UI.createImageView({ width: 320, height: 310, //top: 10 });
for (var t = 0; t < toJSON.length; t++) {
if (t < 3) {
var view = Titanium.UI.createImageView({
width: 320,
height: 310,
//top: 10
});
image_url = toJSON[t];
//start
if (utilities.CheckIfImageExist(utilities.ExtractImageName(image_url))) {
var parent = Titanium.Filesystem.getApplicationDataDirectory();
var picture = Titanium.Filesystem.getFile(parent, 'pictures');
var picturePath = parent + 'pictures/';
Ti.API.info('picturePath: ' + picturePath);
var f = Titanium.Filesystem.getFile(picturePath, utilities.ExtractImageName(image_url));
var blob = f.read();
// here is saved blog file
console.log('Image already downloaded');
var width = blob.width;
var height = blob.height;
//crop so it fits in image view
if (width > height) {
view.image = ImageFactory.imageAsCropped(blob, {
width: height,
height: height,
x: 60,
y: 0
});
} else {
view.image = ImageFactory.imageAsCropped(blob, {
width: (width - 1),
height: (width - 1),
x: 60,
y: 0
});
}
} else {
//do new loop - async causing problems
alert('not downloaded');
// if image is not downloaded we will download it here
utilities.APIGetRequestImage(image_url, function (e) {
alert('begin downloaded');
var status = this.status;
if (status == 200) {
Ti.API.info(this.responseData);
//save to directory
utilities.SaveImageToDirectory(this.responseData, image_url);
//create view
var view = Titanium.UI.createImageView({
width: 320,
height: 310,
//top: 10
});
var width = this.responseData.width;
var height = this.responseData.height;
//crop so it fits in image view
if (width > height) {
var view = Titanium.UI.createImageView({
width: 320,
height: 310,
//top: 10
});
view.image = ImageFactory.imageAsCropped(this.responseData, {
width: height,
height: height,
x: 60,
y: 0
});
// $.scrollableView.addView(view);
viewArr.push(view);
} else {
view.image = ImageFactory.imageAsCropped(this.responseData, {
width: (width - 1),
height: (width - 1),
x: 60,
y: 0
});
viewArr.push(view);
//when t = 3, all views are put inside array, set image view
//if(t==3){
//}
}
}
}, function (err) {
alert('error downloading image');
});
}
}
}
是一种回调方法,它从服务器获取文件并将其下载
如何使这两种方法同时运行?请查看:
for (var t = 0; t < toJSON.length; t++) {
if (t < 3) {
var view = Titanium.UI.createImageView({
width: 320,
height: 310,
//top: 10
});
image_url = toJSON[t];
//start
if (utilities.CheckIfImageExist(utilities.ExtractImageName(image_url))) {
var parent = Titanium.Filesystem.getApplicationDataDirectory();
var picture = Titanium.Filesystem.getFile(parent, 'pictures');
var picturePath = parent + 'pictures/';
Ti.API.info('picturePath: ' + picturePath);
var f = Titanium.Filesystem.getFile(picturePath, utilities.ExtractImageName(image_url));
var blob = f.read();
// here is saved blog file
console.log('Image already downloaded');
var width = blob.width;
var height = blob.height;
//crop so it fits in image view
if (width > height) {
view.image = ImageFactory.imageAsCropped(blob, {
width: height,
height: height,
x: 60,
y: 0
});
} else {
view.image = ImageFactory.imageAsCropped(blob, {
width: (width - 1),
height: (width - 1),
x: 60,
y: 0
});
}
} else {
//do new loop - async causing problems
alert('not downloaded');
// if image is not downloaded we will download it here
utilities.APIGetRequestImage(image_url, (function (t, image_url) {
return function (e) { // <----- wrap callback function
alert('begin downloaded');
var status = this.status;
if (status == 200) {
Ti.API.info(this.responseData);
//save to directory
utilities.SaveImageToDirectory(this.responseData, image_url);
//create view
var view = Titanium.UI.createImageView({
width: 320,
height: 310,
//top: 10
});
var width = this.responseData.width;
var height = this.responseData.height;
//crop so it fits in image view
if (width > height) {
var view = Titanium.UI.createImageView({
width: 320,
height: 310,
//top: 10
});
view.image = ImageFactory.imageAsCropped(this.responseData, {
width: height,
height: height,
x: 60,
y: 0
});
// $.scrollableView.addView(view);
viewArr.push(view);
} else {
view.image = ImageFactory.imageAsCropped(this.responseData, {
width: (width - 1),
height: (width - 1),
x: 60,
y: 0
});
viewArr.push(view);
//when t = 3, all views are put inside array, set image view
//if(t==3){
//}
}
}
};
})(t, image_url), function (err) {
alert('error downloading image');
});
}
}
}
for(var t=0;t高度){
view.image=ImageFactory.imageAsCropped(blob{
宽度:高度,
高度:高度,,
x:60,
y:0
});
}否则{
view.image=ImageFactory.imageAsCropped(blob{
宽度:(宽度-1),
高度:(宽度-1),
x:60,
y:0
});
}
}否则{
//执行新循环-异步导致问题
警报(“未下载”);
//如果图像未下载,我们将在此处下载
APIGetRequestImage(image\uurl)(函数(t,image\uurl){
返回函数(e){//高度){
var view=tianium.UI.createImageView({
宽度:320,
身高:310,
//前10名
});
view.image=ImageFactory.imageAsCropped(this.responseData{
宽度:高度,
高度:高度,,
x:60,
y:0
});
//$.scrollableView.addView(视图);
viewArr.push(视图);
}否则{
view.image=ImageFactory.imageAsCropped(this.responseData{
宽度:(宽度-1),
高度:(宽度-1),
x:60,
y:0
});
viewArr.push(视图);
//当t=3时,所有视图都放在数组中,设置图像视图
//如果(t==3){
//}
}
}
};
})(t,图像url),函数(err){
警报(“下载图像时出错”);
});
}
}
}
通过包装实用程序.APIGetRequestImage
回调,t
和image\u url
被正确地传递。当您说“需要它以同步的方式完成”时,实际上您并没有这样做。您说希望“让两个方法同时运行”,这需要异步
只需交换检查
if(t==3)
(始终为3,即使您确实像@wachme建议的那样对其进行了关闭,那么最后开始的下载(而不是最后结束的下载)只需检查您收到的项目数:if(viewArr.length==3)
。当所有三个回调都执行时,它将是3
,您可以继续执行任务。您的问题是什么?如果图像url未通过if语句的第一次检查,则应在每次迭代时将其传递到if语句的最后一部分。我怀疑由于最后一部分是一个异步函数,它没有正确迭代这是另一个例子-callblacks in Loop不应该读“开始下载”,而应该读“结束下载,开始保存”?看我,这就成功了。这里到底发生了什么?为什么会这样?同步调用大THANKSWrapper函数(闭包)。回调函数使用闭包的内部作用域,当外部作用域改变时,内部作用域不会改变。阅读有关闭包的更多信息:顺便说一下,我添加了一个警报来检查异步函数中的t值,它的顺序似乎是1,0,2,而不是0,1,2-不确定为什么会发生这种情况如果多次尝试,结果可能会不同。这是因为utilities.APIGetRequestImage
执行并不总是花费相同的时间。出于某种原因,第二次呼叫在第一次呼叫之前就结束了。我是否可以通过编程防止这种情况发生?或者,如果硬编码说3个div(3个图像视图)并确保正确的图像根据t值进入正确的视图,会更好吗?
for (var t = 0; t < toJSON.length; t++) {
if (t < 3) {
var view = Titanium.UI.createImageView({
width: 320,
height: 310,
//top: 10
});
image_url = toJSON[t];
//start
if (utilities.CheckIfImageExist(utilities.ExtractImageName(image_url))) {
var parent = Titanium.Filesystem.getApplicationDataDirectory();
var picture = Titanium.Filesystem.getFile(parent, 'pictures');
var picturePath = parent + 'pictures/';
Ti.API.info('picturePath: ' + picturePath);
var f = Titanium.Filesystem.getFile(picturePath, utilities.ExtractImageName(image_url));
var blob = f.read();
// here is saved blog file
console.log('Image already downloaded');
var width = blob.width;
var height = blob.height;
//crop so it fits in image view
if (width > height) {
view.image = ImageFactory.imageAsCropped(blob, {
width: height,
height: height,
x: 60,
y: 0
});
} else {
view.image = ImageFactory.imageAsCropped(blob, {
width: (width - 1),
height: (width - 1),
x: 60,
y: 0
});
}
} else {
//do new loop - async causing problems
alert('not downloaded');
// if image is not downloaded we will download it here
utilities.APIGetRequestImage(image_url, (function (t, image_url) {
return function (e) { // <----- wrap callback function
alert('begin downloaded');
var status = this.status;
if (status == 200) {
Ti.API.info(this.responseData);
//save to directory
utilities.SaveImageToDirectory(this.responseData, image_url);
//create view
var view = Titanium.UI.createImageView({
width: 320,
height: 310,
//top: 10
});
var width = this.responseData.width;
var height = this.responseData.height;
//crop so it fits in image view
if (width > height) {
var view = Titanium.UI.createImageView({
width: 320,
height: 310,
//top: 10
});
view.image = ImageFactory.imageAsCropped(this.responseData, {
width: height,
height: height,
x: 60,
y: 0
});
// $.scrollableView.addView(view);
viewArr.push(view);
} else {
view.image = ImageFactory.imageAsCropped(this.responseData, {
width: (width - 1),
height: (width - 1),
x: 60,
y: 0
});
viewArr.push(view);
//when t = 3, all views are put inside array, set image view
//if(t==3){
//}
}
}
};
})(t, image_url), function (err) {
alert('error downloading image');
});
}
}
}