Javascript 如何将创建用于返回带有$q库的承诺的方法转换为使用ES6承诺。Angularjs应用程序到Angular4+;
由于ES6承诺没有延迟对象,因此在如何将其转换为与ES6承诺一起使用时会产生混淆。我正在研究的一个解决方案是手动向Promise构造函数添加一个不同的对象 原因:我正在将angularjs应用程序转换为angular4,并使用它更好地了解如何使用ES6承诺。我本来打算添加延迟对象,但认为这是一个太多的变通方法Javascript 如何将创建用于返回带有$q库的承诺的方法转换为使用ES6承诺。Angularjs应用程序到Angular4+;,javascript,angularjs,angular,es6-promise,Javascript,Angularjs,Angular,Es6 Promise,由于ES6承诺没有延迟对象,因此在如何将其转换为与ES6承诺一起使用时会产生混淆。我正在研究的一个解决方案是手动向Promise构造函数添加一个不同的对象 原因:我正在将angularjs应用程序转换为angular4,并使用它更好地了解如何使用ES6承诺。我本来打算添加延迟对象,但认为这是一个太多的变通方法 function generateImages() { console.log('generateImagesCalled') // set up pr
function generateImages() {
console.log('generateImagesCalled')
// set up promises
var fullDeferred = $q.defer();
var thumbDeferred = $q.defer();
var resolveFullBlob = blob => fullDeferred.resolve(blob);
var resolveThumbBlob = blob => thumbDeferred.resolve(blob);
var displayPicture = (url) => {
var image = new Image();
image.src = url;
// Generate thumb
var maxThumbDimension = THUMB_IMAGE_SPECS.maxDimension;
var thumbCanvas = _getScaledCanvas(image, maxThumbDimension);
thumbCanvas.toBlob(resolveThumbBlob, 'image/jpeg', THUMB_IMAGE_SPECS.quality);
// Generate full
var maxFullDimension = FULL_IMAGE_SPECS.maxDimension;
var fullCanvas = _getScaledCanvas(image, maxFullDimension);
fullCanvas.toBlob(resolveFullBlob, 'image/jpeg', FULL_IMAGE_SPECS.quality);
}
var reader = new FileReader();
reader.onload = (e) => {
displayPicture(e.target.result);
}
reader.readAsDataURL(vm.currentFile);
return $q.all([fullDeferred.promise, thumbDeferred.promise]).then(results => {
console.log(results);
return {
full: results[0],
thumb: results[1]
}
});
}
在ES6中,它将是
let resolve1 = new Promise<string>((resolve, reject) => {
if (error) {
reject();
} else {
resolve();
}
});
或者您也可以声明承诺数组,然后解析它
let resolvedPromisesArray = [Promise.resolve(val1), Promise.resolve(val2)];
let p = Promise.all(resolvedPromisesArray);
如果其中一个承诺被拒绝,它将失败;如果所有承诺都成功,它将运行;)
在某些特殊情况下,可以公开
解决
和拒绝
以复制延迟:
let pResolve;
let pReject;
const p = new Promise((resolve, reject) => {
pResolve = resolve;
pReject = reject;
});
或者可以形成延迟对象:
const deferred = {};
deferred.promise = new Promise((resolve, reject) => {
Object.assign(deferred, { resolve, reject });
});
由于延迟不是内置的功能,并且容易成为反模式,因此最好仅使用构造函数(如果适用)来解决此问题
在上面的代码中,displayPicture
和承诺不能立即形成,但在load
事件上限制了有效处理情况的方式。它可以通过遵守事件承诺来改进(也有利于进一步转换为async..wait
):
为了提供相同的控制流,promises还应使用角度消化。由于promise内部不依赖于角度服务,因此最后可以有一个摘要:
return blobPromises.then(
() => $rootScope.$apply(),
err => {
$rootScope.$apply();
throw err;
}
);
// or
return $q.resolve(blobPromises);
为什么您要将其转换为ES6 promise?它与Angular digest集成时会有额外的问题,这是$q为您做的事情。我正在将应用程序转换为angular4,并使用它更好地了解如何使用ES6。我本来打算添加延迟对象,但我认为这是一个太多的解决办法。我建议在问题中说明这一点,这将使它对有类似问题的读者更有用。为什么你甚至在不应该使用延迟的情况下提到延迟呢?@Bergi为了完整性起见,因此,读者可以估计选项,并就此做出自己的决定。大多数时候不应该使用延迟并不意味着它们根本不应该被使用。我已经为他们准备了相当多的好用例。@estus谢谢-让它工作了-即使在你的帮助下-它仍然是令人费解的。使用延迟模式已经很长时间了。感觉就像我在学习承诺一样。一个问题:你为什么提到angular4的消化周期。不要认为angular4中有摘要循环。是的,没有摘要(从技术上讲,区域是相似的,会导致自动变化检测)。这个问题不清楚您是在逐步重构A1应用程序,以便稍后将其转换为A4,还是在A4中重写它。上面的示例是经得起未来考验的A1代码,它可以按原样在A4中使用,但不需要$rootScope或$q。
const readerPromise = new Promise(resolve => reader.onload = resolve);
reader.readAsDataURL(vm.currentFile);
const blobPromises = readerPromise.then(e => {
const url = e.target.result;
const fullBlobPromise = new Promise(resolve => {
...
fullCanvas.toBlob(resolve, ...);
});
const thumbBlobPromise = ...;
return Promise.all([fullBlobPromise, thumbBlobPromise]);
});
return blobPromises.then(
() => $rootScope.$apply(),
err => {
$rootScope.$apply();
throw err;
}
);
// or
return $q.resolve(blobPromises);