简体   繁体   English

jQuery 函数返回承诺

[英]jQuery functions returning promises

I have an object (a Floor Area for reference) that belongs to a Category, the Category belongs to a Type.我有一个属于一个类别的 object(参考楼面面积),该类别属于一个类型。 When adding a new object the user can choose an existing, or new, Type and Category.添加新的 object 时,用户可以选择现有的或新的类型和类别。 If the Category and/or Type don't exist a new one should be created.如果类别和/或类型不存在,则应创建一个新的。

For the UI I have two dropdown lists, Type and Categories, as well as the properties for the object.对于 UI,我有两个下拉列表,类型和类别,以及 object 的属性。 These dropdowns can also have new entries added (using select2).这些下拉菜单也可以添加新条目(使用 select2)。 When selecting an existing Type, the Categories dropdown repopulates with the Categories for that Type.选择现有类型时,类别下拉列表会重新填充该类型的类别。

If an existing Type is selected we should use the existing typeId from the dropdown list.如果选择了现有类型,我们应该使用下拉列表中的现有 typeId。 If it's a new type we make a request to create a new Type and return the new typeId.如果它是一个新类型,我们会请求创建一个新类型并返回新的 typeId。 Then we do the same for Categories.然后我们对类别做同样的事情。 The categoryId is then used to create a new object.然后使用 categoryId 创建一个新的 object。

I know in essence what I need to do to achieve this.我本质上知道我需要做些什么来实现这一目标。 In practice I'm struggling a bit with how to format the functions and promises in what they will return.在实践中,我在如何格式化函数和它们将返回的承诺方面有点挣扎。 I can get it working if both Type and Category already exist (code below).如果 Type 和 Category 都已经存在(下面的代码),我可以让它工作。 And with some changes, get it working if both Type and Category don't exist, but not both.通过一些更改,如果 Type 和 Category 都不存在,但不是两者都存在,则让它工作。 I know it's something to do with the way I'm structuring my return types as functions.我知道这与我将返回类型构造为函数的方式有关。

typeIdGet should return either the existing or new typeId, instead it returns an Id if it is existing, but a getJSON function if it doesn't. typeIdGet应该返回现有的或新的 typeId,如果它存在则返回一个 Id,如果不存在则返回一个getJSON function。

categoryIdGet should do the same but take the previously returned typeId if a new Category is required. categoryIdGet应该做同样的事情,但如果需要一个新的 Category,则采用先前返回的 typeId。

How do I structure the two typeIdGet functions to return an Id in either case?在任何一种情况下,如何构造两个 typeIdGet 函数以返回 Id?

How do I structure the two categoryIdGet functions to take the returned typeId from the previous function and return an Id in either case?如何构造两个 categoryIdGet 函数以从先前的 function 中获取返回的 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>

The problem is that (as hinted at in your later comment), they two $.getJSON commands are running in parallel, because you didn't do anything to wait for the first one to finish before running the second one.问题是(正如您稍后的评论中所暗示的那样),它们两个$.getJSON命令并行运行,因为在运行第二个之前,您没有做任何事情来等待第一个完成。

The easiest way to make that happen is to wrap them in functions (and make the functions always return a promise to make them easier to deal with:实现这一点的最简单方法是将它们包装在函数中(并使函数始终返回 promise 以使其更易于处理:

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 ) ) );
    } );
  } );
}

Now, with that you can run them in the order you want:现在,您可以按照您想要的顺序运行它们:

typeIdGet().then( function( typeId ) {
  return categoryIdGet( typeId ).then( function( categoryId ) {
    console.log( "typeId:", typeId, "categoryId:", categoryId );
  } );
} );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM