Как проверить, завершила ли функция асинхронного выполнения выполнение обещаний?

Это ответ уже много раз, но поскольку это первый результат в google, я приведу Java-ответ с примером.

Взгляните на поток особенность. Затем вы можете получить максимальную форму в виде списка таких объектов:

List ourValues = new ArrayList<>();

ourValues.stream().max(comparing(ValuePairs::getMValue)).get()

Кстати, в вашем примере атрибуты должны быть закрытыми. Затем вы можете получить доступ к ним с помощью геттера.

1
задан codingsplash 13 July 2018 в 06:05
поделиться

4 ответа

Вызов решения - это то, что вы должны делать сами. Поскольку foo немедленно возвращается, ваше обещание также немедленно разрешается. Однако, если это соответствует вашим требованиям, вы можете сделать что-то вроде ниже.

function foo(resolve) {
  setTimeout(() => {
    console.log("hello world");
    resolve();
  }, 1000)
}

function bar() {
  return new Promise(function(resolve) {
    foo(resolve)
  })
}

bar().then(() => console.log("foo has completed"))

2
ответ дан Chathura Widanage 17 August 2018 в 13:37
поделиться
  • 1
    Это странный способ программирования с обещаниями. foo () должен просто вернуть свое собственное обещание. – jfriend00 13 July 2018 в 06:25

Я думаю, что ваш код должен быть таким

function foo() {
  return new Promise(function(resolve) {
    setTimeout(() => {
      console.log("hello world");
      resolve();
    }, 1000);
  });
}

function bar() {
  return new Promise(function(resolve) {
    resolve(foo());
  });
}

bar().then(() => console.log("foo has completed"));
0
ответ дан D. Seah 17 August 2018 в 13:37
поделиться
  • 1
    Зачем отмечать функцию async, если вы не используете ее в ожидании – Li357 13 July 2018 в 06:13
  • 2
    Нет причин создавать новое обещание в bar(). Вы можете просто сделать return foo() внутри bar(). И нет причин использовать ключевое слово async. – jfriend00 13 July 2018 в 06:26

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

Ваша функция foo() выполняет асинхронную операцию, но не предлагает оповестить вызывающего абонента или кого-либо еще, когда это сделано. Это то, что вызывает вашу проблему, и нет хорошего способа исправить это, не изменяя foo(). Вот несколько вещей, которые вы можете сделать.

Попросить foo вызвать обратный вызов

Вы можете изменить foo(), чтобы вызвать обратный вызов, когда он будет завершен. Тогда это может выглядеть так:

 function foo(cb){
    setTimeout(()=>{
        console.log("hello world")
        cb(null, true) // callbacks offen pass an error as their first arg or null if there's no error

    },1000)
}

При этом bar() может называть его передачей обратного вызова, а затем либо запускать обратный вызов, либо возвращать обещание. Здесь мы вернем обещание и соединим все это:

function foo(cb){
    console.log("foo called")
    setTimeout(()=>{
        console.log("foo's timeout finished")
        cb(null, true)

    },1000)
}
    
function bar(){
    console.log("car called")
    return new Promise((resolve, reject) =>{
        foo((err, res) => {
            if (err) return reject(err)
            resolve( "foo finished with " + res)
        })
    })
}

bar().then((result)=>console.log("bar has finish and returned: ", result))

Или у Foo есть обещание

Если foo() просто вернул обещание, которое было разрешено, когда оно было закончено, все будет проще, потому что тогда bar() может просто вернуться, а затем пообещать или вызвать .then() и вернуть это, если ему нужно обработать результаты:

function foo(cb) {
  return new Promise(resolve => setTimeout(() => {
    console.log("hello world")
    resolve(true)
  }, 1000))
}

function bar() {
  return foo().then(res => "foo finished with: " + res)
}

bar().then((result) => console.log("bar has finish and returned: ", result))

1
ответ дан Mark Meyer 17 August 2018 в 13:37
поделиться
  • 1
    Второй вариант & gt; 1-й вариант. Предпочтительным является продвижение на самом низком уровне. – jfriend00 13 July 2018 в 07:41
  • 2
    @ jfriend00 согласился. – Mark Meyer 13 July 2018 в 07:42

Вы вызываете вызов setTimeout() в вызове resolve. Это должно исправить это:

function foo(resolve){
setTimeout(()=> { 
  console.log("hello world");
  resolve()
 },1000)
}

function bar(){
  return new Promise(function(resolve){
    return foo(resolve)
  })
}

bar().then(()=>console.log("foo has completed"))
-1
ответ дан MMaks 17 August 2018 в 13:37
поделиться
  • 1
    Это странный способ программирования с обещаниями. foo() должен просто вернуть свое обещание. – jfriend00 13 July 2018 в 06:25
  • 2
    @ jfriend00, функции являются гражданами первого класса и могут быть переданы любым способом. Я думаю, вы применяете персональные шаблоны, которые не связаны с проблемным доменом. Вы можете просмотреть параметр resolve как callback, и это может изменить вашу перспективу – MMaks 13 July 2018 в 06:31
  • 3
    Я не сказал, что это не сработает, но не часто обходится ссылка на resolve и не рекомендуется. Вот почему спецификация обещания не имеет отложенных объектов, только обещания с исполнителем обещаний. Любой, кто регулярно выступает с обещаниями, скажет вам, что foo должен просто вернуть свое обещание здесь. Это более чистый дизайн обещаний. Да, весь дизайн - это мнение, но когда большинство людей, получивших образование по этой теме, будут иметь такое же мнение о дизайне, это общий и принятый дизайн. – jfriend00 13 July 2018 в 06:35
  • 4
    Рассматривая это как обратный вызов, вы смешиваете обещания и обратные вызовы, что является плохим дизайнерским решением. Это просто усложняет все. Хорошая перспективная конструкция обещает асинхронные операции на самом низком уровне, а затем использует только обещание управления потоком. Я скорее сомневаюсь, что вы выиграете любой аргумент, что это предпочтительный дизайн, и это то, о чем мой первый комментарий. – jfriend00 13 July 2018 в 06:37
  • 5
    Я согласен с @ jfriend00 - это немного странно, хотя не , что намного отличается от передачи обратного вызова к foo. Настоящая трудность возникает в более реалистичном сценарии, когда вы хотели учесть возможность того, что foo может иметь ошибку. Итак, вам нужно будет передать функции resolve и reject в foo. Но это не так, как работают большинство функций, основанных на обратном вызове - они предпочитают шаблон callback(err, result). Что оставляет вас с foo, который не работает так, как ожидали многие люди, что приводит к ошибкам. – Mark Meyer 13 July 2018 в 06:54
Другие вопросы по тегам:

Похожие вопросы: