如何在这个例子中使用 Angular JS $q 服务?

How can I use Angular JS $q service in this example?

在下面的示例中,我需要等待 drawFunc 方法完成,然后再继续添加不透明度并最终将 foregroundPath 添加到 Kinetic 中的图层。

在使用 Angular JS $q 服务将 foregroundPath 值添加到层之前,有什么方法可以 "wait" 获得 foregroundPath 值?

var foregroundPath = new Kinetic.Shape({
    x: x,
    y: y,
    drawFunc: function(context){
        context._context.fillStyle = graphic.fill;
        try{
            fabricSVG.render(context);
        }
        catch (TypeError) {
            console.log('Caught TypeError!');
        }
    },
    fill: graphic.fill,
    name: 'graphicMainColor',
    scale: {x: imageScale, y: imageScale},
    rotation: graphic.rotation
});

foregroundPath.opacity(graphicOpactiy);

var imageLayer = new Kinetic.Layer({name: layerName});
imageLayer.add(foregroundPath);
kineticStage.add(imageLayer);

更新 #2

@anthony-c - 这里没有调用 successerror 回调。相反,我使用 $q.all() 因为我也在为 backgroundPath 做同样的事情(我只是为了简洁没有包括它)。在这个例子中,success 方法总是首先被调用。当我执行 console.log() 时,我可以告诉脚本执行 first 所有承诺的 success 然后 then 它执行什么drawFunc里面。它不应该在为所有承诺运行 success 方法之前先执行 drawFunc 吗?

var backgroundPathDeferred = $q.defer();
var foregroundPathDeferred = $q.defer();

// Graphic Shadow Color
var backgroundPath = new Kinetic.Shape({
    x: x - 1,
    y: y - 1,
    drawFunc: function(context){
        context._context.fillStyle = shadowFill;
        try{
            fabricSVG.render(context);
        }
        catch (TypeError) {
            console.log('Caught TypeError!');
            backgroundPathDeferred.reject(TypeError);
        }
        backgroundPathDeferred.resolve();
    },
    fill: shadowFill,
    name: 'graphicShadowColor',
    scale: {x: imageScale, y: imageScale},
    rotation: graphic.rotation
});

// Graphic Main Color
var foregroundPath = new Kinetic.Shape({
    x: x,
    y: y,
    drawFunc: function(context){
        context._context.fillStyle = graphic.fill;
        try{
            fabricSVG.render(context);
        }
        catch (TypeError) {
            console.log('Caught TypeError!');
            foregroundPathDeferred.reject(TypeError);
        }
        foregroundPathDeferred.resolve();
    },
    fill: graphic.fill,
    name: 'graphicMainColor',
    scale: {x: imageScale, y: imageScale},
    rotation: graphic.rotation
});

var promises = {
    'foreground': foregroundPathDeferred,
    'background': backgroundPathDeferred
};
$q.all(promises).then(function(){
    console.log('All promises resolved.', backgroundPath, foregroundPath);
    backgroundPath.opacity(shadowOpacity);
    foregroundPath.opacity(graphicOpactiy);

    var imageLayer = new Kinetic.Layer({name: layerName});
    imageLayer.add(backgroundPath);
    imageLayer.add(foregroundPath);
    kineticStage.add(imageLayer);
    kineticStage.find('.background').setZIndex(9999);
    $('canvas').css({'width': '100%', 'height': '100%'});
}, function(error){
    console.log('Caught error!', error, foregroundPath, backgroundPath);
});

您可以在 drawFunc 退出之前移动该命令:

var foregroundPath = new Kinetic.Shape({
    x: x,
    y: y,
    drawFunc: function(context){
        context._context.fillStyle = graphic.fill;
        try{
            fabricSVG.render(context);
            foregroundPath.opacity(graphicOpactiy); // <-- move to here
            imageLayer.add(foregroundPath);  // <-- move to here
        }
        catch (TypeError) {
            console.log('Caught TypeError!');
        }
    },
    fill: graphic.fill,
    name: 'graphicMainColor',
    scale: {x: imageScale, y: imageScale},
    rotation: graphic.rotation
});

var imageLayer = new Kinetic.Layer({name: layerName});
kineticStage.add(imageLayer);

用 $q 做

var foregroundPathDeferred = $q.defer();
var foregroundPath = new Kinetic.Shape({
    x: x,
    y: y,
    drawDeferred: foregroundPathDeferred,
    drawFunc: function(context){
        context._context.fillStyle = graphic.fill;
        try{
            fabricSVG.render(context);
            this.attrs.drawDeferred.resolve();
        }
        catch (error) {
            this.attrs.drawDeferred.reject(error);
        }

    },
    fill: graphic.fill,
    name: 'graphicMainColor',
    scale: {x: imageScale, y: imageScale},
    rotation: graphic.rotation
});
foregroundPathDeferred.promise.then(function(){
    foregroundPath.opacity(graphicOpactiy);
},function(error){
    console.log('Caught error!', error);
});
var imageLayer = new Kinetic.Layer({name: layerName});
imageLayer.add(foregroundPath);
kineticStage.add(imageLayer);