我有一个属于类别的对象(供参考的地板区域),该类别属于一种类型。添加新对象时,用户可以选择现有的或新的“类型”和“类别”。如果类别和/或类型不存在,则应创建一个新的类别。
对于UI,我有两个下拉列表,类型和类别,以及对象的属性。这些下拉菜单也可以添加新条目(使用select2)。选择现有类型时,“类别”下拉列表将使用该类型的“类别”重新填充。
如果选择了现有的Type,则应使用下拉列表中的现有typeId。如果是新类型,我们会请求创建一个新类型并返回新的typeId。然后,对类别执行相同的操作。然后,categoryId用于创建新对象。
我本质上知道实现此目标需要做什么。在实践中,我在如何格式化函数和返回的承诺方面有些挣扎。如果类型和类别都已经存在,我可以使它工作(下面的代码)。并进行一些更改,如果Type和Category都不存在,但两者都不存在,则使其正常工作。我知道这与将返回类型构造为函数的方式有关。
typeIdGet
应该返回现有的或新的typeId,如果存在则返回一个Id,否则返回一个getJSON
函数。
categoryIdGet
应该执行相同的操作,但是如果需要新的Category,则使用先前返回的typeId。
在两种情况下,如何构造两个typeIdGet函数以返回ID?
如何构造两个categoryIdGet函数以从上一个函数获取返回的typeId并在两种情况下都返回一个ID?
<script>
// ... click event handler and some code to get the selected Type and Category ...
// code below handles the promises
var myTypeId, myCategoryId;
if (existingType) { // existing type, return the selected Id
typeIdGet = $.when(Number(selectedTypeId)); // this is a promise that resolves immediately
} else { // new Type we need to create one and get the new Id
typeIdGet = $.getJSON(
"Dimensions/Create?handler=NewType",
{
floorAreaTypeName: selectedTypeOption.text()
},
function (response) { // returns new Id
return Number(JSON.parse(response));
}
);
}
if (existingCategory) {
categoryIdGet = $.when(Number(selectedCategoryId));
} else {
categoryIdGet = $.getJSON(
"Dimensions/Create?handler=NewCategory",
{
floorAreaTypeId: myTypeId, // this should be passed in
floorAreaCategoryName: selectedCategoryOption.text()
},
function (response) { // returns new Id
return Number(JSON.parse(response));
}
);
}
typeIdGet.then(function (typeId) {
myTypeId = typeId;
return categoryIdGet; // Can we not pass in the typeId here?
}).then(function (categoryId) {
myCategoryId = categoryId;
alert("myTypeId: " + myTypeId + " myCategoryId:" + myCategoryId);
// Create new floor area here with the categoryId
}).fail("Something went wrong");
</script>
答案 0 :(得分:1)
问题是(如您后面的评论中所暗示),这两个$.getJSON
命令 并行运行,因为您没有做任何事情来等待第一个命令在运行第二个之前完成。
最简单的方法是将它们包装在函数中(并使函数始终返回一个使它们易于处理的承诺:
function typeIdGet() {
if ( existingType ) return Promise.resolve( Number( selectedTypeId ) );
return new Promise( function( resolve, reject ) {
$.getJSON( `Dimensions/Create?handler=NewType`, {
floorAreaTypeName : selectedTypeOption.text(),
}, function( response ) {
resolve( Number( JSON.parse( response ) ) );
}
} );
}
function categoryIdGet( typeId ) {
if ( existingCategory ) return Promise.resolve( Number( selectedCategoryId ) );
return new Promise( function( resolve, reject ) {
$.getJSON( 'Dimensions/Create?handler=NewCategory', {
floorAreaTypeId : typeId.
floorAreaCategoryName : selectedCategoryOption.text(),
}, function( response ) {
resolve( Number( JSON.parse( response ) ) );
} );
} );
}
现在,您可以按照想要的顺序运行它们了:
typeIdGet().then( function( typeId ) {
return categoryIdGet( typeId ).then( function( categoryId ) {
console.log( "typeId:", typeId, "categoryId:", categoryId );
} );
} );