在下一次循环迭代之前等待承诺结果
await promise result before next loop iteration
我在每个循环迭代中 运行 调用一个函数,但是我需要确保在下一次迭代 运行 之前收到回调(成功)。当我 运行 下面的代码 运行 循环,然后控制台显示所有回调结果。
var getExerciseImages = function(exerciseImages) {
var deferred = $q.defer();
var imageColumns = [];
var imageObject = {};
for (var i = 0; i < exerciseImages.length; i++) {
var url = 'http://files.s3.amazonaws.com/medium/' + exerciseImages[i] + '.jpg'
convertImgToBase64URL(url).then(function(result) {
imageObject = {
image: result,
fit: [200, 200]
};
imageColumns.push(imageObject);
});
};
deferred.resolve(imageColumns);
return deferred.promise;
};
调用外部函数:
function convertImgToBase64URL(url, callback, outputFormat) {
var deferred = $q.defer();
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS'),
ctx = canvas.getContext('2d'),
dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
// callback(dataURL);
deferred.resolve(dataURL);
canvas = null;
};
img.src = url;
return deferred.promise;
};
如果有更好的方法,我愿意接受有关其他方法的建议吗?
异步操作无法停止脚本的执行,但是我们可以重构您的代码以避免 deferred anti-pattern and instead make use of $q#resolve
and $q#all
以便使用 Promises 专门处理所有数据和逻辑。
var getExerciseImages = function (exerciseImages) {
// Create a resolved Promise whose value is `exerciseImages` array
// Use 'when' in place of 'resolve' if using Angular
return $q.resolve(exerciseImages).then(function (arr) {
// Map each element to a Promise created by `convertImgToBase64URL`
// and wait for them all to resolve by wrapping the resulting
// array of Promises in `$q#all`
return $q.all(arr.map(function (url) {
var url = 'http://files.s3.amazonaws.com/medium/' + url + '.jpg'
return convertImgToBase64URL(url).then(function (result) {
return {
image: result,
fit: [200, 200]
};
});
}));
});
};
此方法的结果将是一个 Promise,其值是一个对象数组,每个对象具有两个属性 image
和 fit
:
var images = []; // An array of URLs
getExerciseImages(images).then(function (data) {
console.log(data); // => [{image, fit}, ...]
});
请注意,在 ES7 中有 async
functions 可以 await
ed。
我在每个循环迭代中 运行 调用一个函数,但是我需要确保在下一次迭代 运行 之前收到回调(成功)。当我 运行 下面的代码 运行 循环,然后控制台显示所有回调结果。
var getExerciseImages = function(exerciseImages) {
var deferred = $q.defer();
var imageColumns = [];
var imageObject = {};
for (var i = 0; i < exerciseImages.length; i++) {
var url = 'http://files.s3.amazonaws.com/medium/' + exerciseImages[i] + '.jpg'
convertImgToBase64URL(url).then(function(result) {
imageObject = {
image: result,
fit: [200, 200]
};
imageColumns.push(imageObject);
});
};
deferred.resolve(imageColumns);
return deferred.promise;
};
调用外部函数:
function convertImgToBase64URL(url, callback, outputFormat) {
var deferred = $q.defer();
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS'),
ctx = canvas.getContext('2d'),
dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
// callback(dataURL);
deferred.resolve(dataURL);
canvas = null;
};
img.src = url;
return deferred.promise;
};
如果有更好的方法,我愿意接受有关其他方法的建议吗?
异步操作无法停止脚本的执行,但是我们可以重构您的代码以避免 deferred anti-pattern and instead make use of $q#resolve
and $q#all
以便使用 Promises 专门处理所有数据和逻辑。
var getExerciseImages = function (exerciseImages) {
// Create a resolved Promise whose value is `exerciseImages` array
// Use 'when' in place of 'resolve' if using Angular
return $q.resolve(exerciseImages).then(function (arr) {
// Map each element to a Promise created by `convertImgToBase64URL`
// and wait for them all to resolve by wrapping the resulting
// array of Promises in `$q#all`
return $q.all(arr.map(function (url) {
var url = 'http://files.s3.amazonaws.com/medium/' + url + '.jpg'
return convertImgToBase64URL(url).then(function (result) {
return {
image: result,
fit: [200, 200]
};
});
}));
});
};
此方法的结果将是一个 Promise,其值是一个对象数组,每个对象具有两个属性 image
和 fit
:
var images = []; // An array of URLs
getExerciseImages(images).then(function (data) {
console.log(data); // => [{image, fit}, ...]
});
请注意,在 ES7 中有 async
functions 可以 await
ed。