Как сделать .then полностью fini sh, прежде чем перейти к следующему? - PullRequest
0 голосов
/ 28 марта 2020

Итак, я добавляю учреждение в базу данных, затем добавляю специальное предложение в базу данных. В заведении может быть от 1 до Множество специальных предложений, поэтому я пытаюсь создать отношение под 3 .then(). Дело в том, что 3-й .then() выполняется до учреждения, и в базу данных добавляется спец. Мне нужно сначала добавить учреждение и спец. В базу данных, потому что мне нужно получить их objectIds, var establishmentObjectId; и var specialObjectId;

Как я могу go убедиться, что получены учреждение и специальные objectIds перед тем как установить связь?

    //Save the establishment objectId
    var establishmentObjectId;
    //Save the special objectID
    var specialObjectId;

    //Save establishment
    .then(() => {
        //Get the add form data
        var addName = document.getElementById('add_name');
        var addCountry = document.getElementById('add_country');
        var addEstablishmentType = document.getElementById('add_establishment_type');
        var addCuisineType = document.getElementById('add_cusine_type');

        //Create establishment from user's enteries
        var establishment = {
            Name: addName.value,
            Address: addAddress.value,
            Suburb: addSuburb.value,
            Country: addCountry.value,
            Cuisine_Type: addCuisineType.value,
            Establishment_Type: addEstablishmentType.value
        }

        //Save establishment to db
        Backendless.Data.of('Establishment').save( establishment )
        .then( function( savedObject ) {
            establishmentObjectId = savedObject.objectId;
            console.log( "new Establishment instance has been saved" );
          })
        .catch( function( error ) {
            console.log( "an error has occurred " + error.message );
          });
    })
    //Save special
    .then(() => {
        //Get the add form data
        var addCategory = document.getElementById('add_category');
        var addTypeOfSpecial = document.getElementById('add_type_of_special');
        var addDescription = document.getElementById('add_description');

        //Create special from user's enteries
        var special = {
            Category: addCategory.value,
            Type_Of_Special: addTypeOfSpecial.value,
            Description: addDescription.value
        }

        //Save special to db
        Backendless.Data.of('Special').save( special )
        .then( function( savedObject ) {
            specialObjectId = savedObject.objectId;
            console.log( "new Special instance has been saved" );
            })
        .catch( function( error ) {
            console.log( "an error has occurred " + error.message );
            });
    })
    //Add special to establishment/form relation
    .then(() => {

        //These are undefined even though they are declared above
        console.log(establishmentObjectId);
        console.log(specialObjectId);

        var parentObject = { objectId:establishmentObjectId };
        var childObject = { objectId:specialObjectId };
        var children = [ childObject ];

        Backendless.Data.of( "Establishment" ).addRelation( parentObject, "establishmentSpecials", children )
        .then( function( count ) {
          console.log( "relation has been set" );
        })
        .catch( function( error ) {
          console.log( "server reported an error - " + error.message );
        });

    })

Большое спасибо

1 Ответ

1 голос
/ 28 марта 2020

Всякий раз, когда вы находитесь в цепочке Promise, в 99% случаев, когда вы создаете новое Promise (с помощью вызова API или с new Promise, et c), вы должны вернуть его или иным образом поставить это вместе с чем-то другим (например, Promise.all и возврат , что ). Это будет означать, что возможные отклонения могут быть обработаны на более высоком уровне, и будет означать, что следующий .then в цепочке начнется только после завершения предыдущего .then.

Изменение каждый

Backendless.Data.of(

до

return Backendless.Data.of(

Кроме того, вы, вероятно, не хотите быть catch на каждом уровне, как вы делаете в настоящее время - всякий раз, когда вы catch, вы превращаете отклоненное обещание в разрешенное обещание, и последующие .then могут выполняться при условии, что все в предыдущих .then завершилось успешно. При таких последовательных асинхронных операциях, если в любом месте есть ошибка , вы, вероятно, захотите остановить весь процесс, а не пытаться продолжить в любом случае (что может привести к ошибкам).

Например, , если Backendless.Data.of('Establishment').save терпит неудачу, то establishmentObjectId никогда не назначается, и попытка использовать его позже в финальном .then не будет работать. То же самое и с specialObjectId.

Для этого кода есть и лучший шаблон: вместо использования двух отдельных .then, один для получения establishmentObjectId и один для получения specialObjectId, подумайте над тем, чтобы эти операции выполнялись параллельно, и запустите финальный .then после того, как они будут выполнены через Promise.all. Что-то вроде:

const getEstablishmentObjectId = () => {
  //Get the add form data
  // ...
  //Create establishment from user's enteries
  var establishment = {
    // ...
  }
  //Save establishment to db
  return Backendless.Data.of('Establishment').save(establishment)
    .then(savedObject => savedObject.objectId);
};
const getSpecialObjectId = () => {
    // ...
    return Backendless.Data.of('Special').save(special)
      .then(savedObject => savedObject.objectId);
};

Promise.all([
  getEstablishmentObjectId(),
  getSpecialObjectId(),
]).then(([establishmentObjectId, specialObjectId]) => {
    console.log(establishmentObjectId);
    console.log(specialObjectId);
    var parentObject = {
      objectId: establishmentObjectId
    };
    // etc
  })
  .catch((error) => {
    console.log('Error', error);
  });
...