Использование JavaScript Promise асинхронно

1

Здесь проблема - я вызываю функцию и которая, возможно, отображает диалог несколько раз и ждет, пока пользователь нажмет OK. Затем после этого - я хочу сделать что-то еще.

Я думаю, что решение требует использования Promise. Но асинхронный характер вызова dialog.alert() отбрасывает меня.

function a()
{
if ( condition_ok )
{
   // there could be multiple dialogs
   //
   for ( int i = 0; i < 2; ++i )
      dialog.alert("press ok").then ( ()=> { console.log("done"); } );
  }
}
a();
// call b() after all the dialogs have been closed in a()
b();
  • 0
    for ( int i = 0; i < 2; ++i ) ... int?
  • 0
    предполагается, что это псевдокод ... это то, что происходит, когда вы работаете с несколькими языками одновременно.
Теги:
if-statement
promise

4 ответа

3
Лучший ответ

Если вы находитесь в среде с функциями стрелок (что предлагает ваш код), но не поддерживает async/await (что является отличным ответом на @guest271314), вы можете использовать следующее:

function a() {
    var p = Promise.resolve();
    if (condition_ok) {
        // there could be multiple dialogs
        //
        for (var i = 0; i < 2; ++i) {
            p = p
            .then(() => dialog.alert('press ok'))
            .then(() => {
                console.log('done');
            });
        }
    }
    return p;
}
a().then(b);

Примечание: каждый диалог будет ждать, пока предыдущий "закроется", и я думаю, что это ваш код

  • 0
    ой, глупая опечатка
  • 0
    Я не пробовал это, потому что, кажется, есть некоторые проблемы с синтаксисом. и что делает р = р ??
Показать ещё 3 комментария
0

Используйте Promise.all().

let targets = []
for (let i = 0; i < 2; i++) {
    targets.push(dialog.alert('press ok'))
}
Promise.all(targets).then(([result1, result2]) => {
    b();
})
  • 0
    Спасибо - работает как положено - даже если цикл for не введен.
0

Вы можете использовать async/await Promise.all() или Promise.all() и Array.prototype.map()

async function a() {
  if ( condition_ok ) {
    // there could be multiple dialogs
    //
    for ( let i = 0; i < 2; i++ ) {
      let curr = await dialog.alert("press ok");
      console.log("done");
    }
  }
  return
}
// call b() after all the dialogs have been closed in a()
a().then(() => b(), err => console.error(err));
0

Проблема, с которой вы сталкиваетесь, заключается в том, что вам нужно дождаться, когда все асинхронное alert будет выполнено до вызова b. Вы можете сохранить все ваши асинхронные вызовы в массиве, а затем использовать Promise.all() чтобы убедиться, что все они выполнены до вызова b. Вот как вы могли это сделать

// Faking data/objects - START
const condition_ok = true;
const dialog = {
  alert() {
    return new Promise((resolve, reject) => {
      resolve("Done");
    })
  }
}
const b = () => {
  console.log("Call b()")
}
// Faking data/objects - END

function a() {
  let promises = [];
  if (condition_ok) {
    for (let i = 0; i < 2; ++i) {
      promises.push(dialog.alert("press ok").then(() => {
        console.log('Done with alert() for ${i}');
      }));
    }
  }
  return promises;
}

Promise.all(a()).then(results => {
  // call b() after all the dialogs have been closed in a()
  b();
});
  • 0
    a () возвращает неопределенное значение condition_ok, равное false.
  • 0
    Вы правы. Пропустил это. Отредактировал код.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню