user2061886 user2061886 - 21 days ago 5
Javascript Question

trying to convert a promise to a generator

I'm trying to convert my promise function into a generator function but am struggling a little to accomplish this.

I keep getting this in my console log:

var myGen {[[GeneratorStatus]]: "suspended"}


when I wrote it as a promise, it looked like this:

function maxYvalue2() {

return Rpt_scn_cost_v.find({filter: { where: {scenario_id: $stateParams.id}}}).$promise.then(function(response){
var maxYvalue = 0;
var currMaxYvalue = 0;
for (var i=0;i<response.length;i++) {
var currMaxYvalue = parseFloat(response[i].cur_cost) + parseFloat(response[i].tgt_cost);
if (currMaxYvalue > maxYvalue) {
maxYvalue = currMaxYvalue;
};
}
return maxYvalue;
});

};


maxYvalue2().then(function(maxYvalue) {


var mxY = maxYvalue

console.log('var', mxY)




$scope.options_scn_cst = {
chart: {
type: 'lineChart',
height: 450,
margin : {
top: 20,
right: 20,
bottom: 40,
left: 55
},
x: function(d){ return d.x; },
y: function(d){ return d.y; },
useInteractiveGuideline: true,
dispatch: {
stateChange: function(e){ console.log("stateChange"); },
changeState: function(e){ console.log("changeState"); },
tooltipShow: function(e){ console.log("tooltipShow"); },
tooltipHide: function(e){ console.log("tooltipHide"); }
},
xAxis: {
axisLabel: '',
tickFormat: function(d) { return d3.time.format('%b %y')(new Date(d)); }
},
yDomain: [0, mxY], // <============ I then set mxY here in the $scope object
yAxis: {
axisLabel: '$ / month',
tickFormat: function(d){
return d3.format('$,.0f')(d);
},
axisLabelDistance: -10
},
callback: function(chart){}
},
title: {
enable: true,
text: 'Scenario Costs Over Time'
},
subtitle: {
enable: false,
text: 'Put your Subtitle here.',
css: {
'text-align': 'center',
'margin': '10px 13px 0px 7px'
}
},
caption: {
enable: false,
html: 'Put your Caption Here.',
css: {
'text-align': 'justify',
'margin': '10px 13px 0px 7px'
}
}
};

//console.log($scope.data_scn_cst);
});


and then I tried to re-write as a generator like this:

var myGen = function*() {

var maxYvalue = 0;
var currMaxYvalue = 0;

var response = yield Rpt_scn_cost_v.find({filter: { where: {scenario_id: $stateParams.id}}});

for (var i=0;i<response.length;i++) {
var currMaxYvalue = parseFloat(response[i].cur_cost) + parseFloat(response[i].tgt_cost);
if (currMaxYvalue > maxYvalue) {
maxYvalue = currMaxYvalue;
};
}

};

var mxY = myGen();

console.log(mxY.next(1));



console.log('var', mxY)




$scope.options_scn_cst = {
chart: {
type: 'lineChart',
height: 450,
margin : {
top: 20,
right: 20,
bottom: 40,
left: 55
},
x: function(d){ return d.x; },
y: function(d){ return d.y; },
useInteractiveGuideline: true,
dispatch: {
stateChange: function(e){ console.log("stateChange"); },
changeState: function(e){ console.log("changeState"); },
tooltipShow: function(e){ console.log("tooltipShow"); },
tooltipHide: function(e){ console.log("tooltipHide"); }
},
xAxis: {
axisLabel: '',
tickFormat: function(d) { return d3.time.format('%b %y')(new Date(d)); }
},
yDomain: [0, mxY], // <============ I then set mxY here in the $scope object
yAxis: {
axisLabel: '$ / month',
tickFormat: function(d){
return d3.format('$,.0f')(d);
},
axisLabelDistance: -10
},
callback: function(chart){}
},
title: {
enable: true,
text: 'Scenario Costs Over Time'
},
subtitle: {
enable: false,
text: 'Put your Subtitle here.',
css: {
'text-align': 'center',
'margin': '10px 13px 0px 7px'
}
},
caption: {
enable: false,
html: 'Put your Caption Here.',
css: {
'text-align': 'justify',
'margin': '10px 13px 0px 7px'
}
}
};

Answer

Generators are not a replacement for promises.

If you want to simplify your syntax and avoid then calls, use async/await (possibly with a trans­piler). The execution will still be asynchronous of course, there's no way to change that. You would write

async function maxYvalue2() {
    var response = await Rpt_scn_cost_v.find({filter: { where: {scenario_id: $stateParams.id}}}).$promise;
//                 ^^^^^
    var maxYvalue = 0;
    var currMaxYvalue = 0;
    for (var i=0;i<response.length;i++) {
        var currMaxYvalue = parseFloat(response[i].cur_cost) + parseFloat(response[i].tgt_cost);
        if (currMaxYvalue > maxYvalue) {
            maxYvalue = currMaxYvalue;
        };
    }
    return maxYvalue;
}

which is exactly equivalent to the function maxYvalue2 that you currently have, and it still returns a promise, so you'd call it in exactly the same way.