Обещание JavaScript не ожидает асинхронного вызова

Я работаю с обещаниями JavaScript, но в некоторой степени новичок в них и у меня есть некоторые проблемы. В приведенном ниже коде «todoService.addTodo (description);» это асинхронный вызов сервера. Однако код не ждет "todoService.addTodo (description);" для завершения и вместо этого продолжает выполнение кода, что означает, что «test» всегда равно нулю. Я использую обещания, потому что думал, что это поможет справиться с асинхронными вызовами, я просто не понимаю концепцию или просто делаю что-то не так синтаксически?

let promise = new Promise(function (resolve, reject){
  let test = todoService.addTodo(description);
  console.info(test)

  if (test) {
     console.info("GOOD");
     resolve("OK");
  } else {
      console.info("BAD");
      reject("Unable to connect to server");
  }
});

promise.then(function(result) {
       console.info(result);
    }, function(err) {
        alert(err);
    });

Вот реализация addTodo ():

addTodo: function (description) {
        serv.todoUrl ='http://localhost:8080/add?description=' + description;
        serv.todoResource = $resource(serv.todoUrl);
        serv.todoResource.save().$promise.then(function (data) {
            console.info(data);
            let toReturn = {result: data.result, details: data.details};
            console.info(toReturn);
            return toReturn;
        }, function (error) {
            return null;
        });

Если todoService.addTodo (description) не возвращает обещание, невозможно остановить его выполнение. вы должны использовать обещание из todoService.addTodo (description)

Dov Benyomin Sohacheski 09.06.2018 21:16

Обозначен ли toolService.addToDo как async? Или это обещание? В первом случае отметка вашей внутренней функции как async и await - это то, что вам нужно, в другом - возврат todoService.addTodo (description) с цепочкой then будет выходом.

Icepickle 09.06.2018 21:17

Вы не понимаете концепцию. Я бы рекомендовал сначала прочитать об этом, посмотрите, сможете ли вы решить проблему самостоятельно, как только получите более четкую картину. MDN обычно является хорошим местом для начала: developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/… - Если после этого у вас все еще возникают проблемы, мы можем продолжить.

Máté Safranka 09.06.2018 21:20

@DovBenyominSohacheski Я добавил свою реализацию addTodo, чтобы вы могли ее увидеть. Он сам по себе выполняет обещание.

Joe Smith 09.06.2018 21:21

Избегайте Антипаттерн конструктора Promise и просто return - это цепочка обещаний от addTodo!

Bergi 09.06.2018 22:08
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
5
47
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если test - это обещание, то if (test) - неправильный способ с этим справиться. Более того, вам не следует создавать new Promise, если addTodo уже дает обещание.

Все, что вам понадобится, это:

todoService.addTodo(description).then(function(result) {
    console.info(result);
}, function(err) {
    alert(err);
});

Теперь, когда вы также добавили реализацию addToDo в свой вопрос, оказалось, что ему не хватает return обещания, которое вы там создали, поэтому он просто вернул undefined, что, очевидно, не является обещанием. Добавьте сюда return:

addTodo: function (description) {
    serv.todoUrl ='http://localhost:8080/add?description=' + description;
    serv.todoResource = $resource(serv.todoUrl);
    return serv.todoResource.save().$promise.then(function (data) {
//  ^^^^^
        console.info(data);
        let toReturn = {result: data.result, details: data.details};
        console.info(toReturn);
        return toReturn;
    }, function (error) {
        return null;
    });

Обратите внимание, что другие операторы return находятся в относительных функциях обратного вызова, которые выполняются асинхронно, поэтому они не предоставляют возвращаемое значение для addToDo, но предоставляют разрешающее значение для обещания.

NB: Поскольку вы обрабатываете случай отклонения в addToDo и не каскадируете ошибку, а просто возвращаете null, addToDo в этом случае будет представлять не отклоненное обещание, а выполненное. Если вы предпочитаете, чтобы вызывающий addToDo получал отклоненное обещание в этом случае, просто удалите функцию обработчика отклонения из addToDo.

Большое спасибо за помощь. То, что вы говорите, имеет смысл, но я все еще немного сбит с толку. Насколько я понимаю, в обещании вы должны указать resolve () и reject (). Если serv.todoResource.save (). $ Обещание является объектом обещания, значит ли это, что он уже реализовал resolve () и reject ()? И если это так, не следует ли мне просто возвращать "serv.todoResource.save (). $ Prom", а не serv.todoResource.save (). $ Prom.then (function) {...} ;?

Joe Smith 09.06.2018 21:41

Во-первых: да, save().$promise возвращает объект обещания, поэтому нет необходимости делать resolve или reject: вам это нужно только тогда, когда вам нужно синтезировать обещание с нуля. Возвращаете ли вы $promise как есть или добавляете then, решать вам. По-видимому, вы хотели, чтобы что-то было сделано после того, как этот $promise разрешился, и поэтому вы добавили then для этого. Но этот then также возвращает обещание, так что вы все еще в порядке. В этом сила цепочки обещаний: вы продолжаете получать обещание от цепочки then.

trincot 09.06.2018 22:06

Другие вопросы по теме