Избегайте вложенных обещаний - PullRequest
0 голосов
/ 13 мая 2018

Я получаю «Избегать вложенных обещаний» (для jslint) для следующей функции.Как я могу написать это без вложенных обещаний?

function deleteUIDsFromDBForKey(rootkey, users_uids) {
  return retrieveUIDsFromDBForKey(rootkey)
    .then(uids => {
      let diff = uids.diff(users_uids)
      let deletes = []
      diff.forEach(key => {
        deletes.push(firebase.database().ref(rootkey + "/" + key).remove())
      })
      return Promise.all(deletes)
        .then(value => {
          return diff
        })
    })
}

Ответы [ 2 ]

0 голосов
/ 13 мая 2018

В этом случае, я думаю, что jsLint просто вводит вас в заблуждение в более сложный код Иногда вы получаете это из linter, и лучший вариант в этом случае - обойти linter для определенной строки кода или функции или определенного правила linter.

Это самая простая и понятная реализация вашего кода, о которой я могу подумать (которая должна быть вашим приоритетом):

function deleteUIDsFromDBForKey(rootkey, users_uids) {
    return retrieveUIDsFromDBForKey(rootkey).then(uids => {
        const diff = uids.diff(users_uids);
        // wait for all deletes to be done, then return diff
        return Promise.all(diff.map(key => {
            return firebase.database().ref(rootkey + "/" + key).remove();
        })).then(() => diff);
    });
}

Или, используя Bluebird's .map(), вы можете сделать это:

// using Bluebird's Promise.map()
function deleteUIDsFromDBForKey(rootkey, users_uids) {
    return retrieveUIDsFromDBForKey(rootkey).then(uids => {
        const diff = uids.diff(users_uids);
        // wait for all deletes to be done, then return diff
        return Promise.map(diff, key => {
            return firebase.database().ref(rootkey + "/" + key).remove();
        }).then(() => diff);
    });
}

Или, используя async / await:

async function deleteUIDsFromDBForKey(rootkey, users_uids) {
    const uids = await retrieveUIDsFromDBForKey(rootkey);
    const diff = uids.diff(users_uids);
    await Promise.all(diff.map(key => {
        return firebase.database().ref(rootkey + "/" + key).remove();
    }));
    return diff;
}

У меня не установлен jsLint с поддержкой ES7, но последний вариант должен избегать предупреждения о вложенности. Первые два, вероятно, нет, но попытка избежать этого предупреждения только ухудшит код, поэтому, IMO, вам следует просто отключить предупреждение.

0 голосов
/ 13 мая 2018

Последние then можно переместить в основную цепочку, вернув результат Promise.all:

function deleteUIDsFromDBForKey(rootkey, users_uids) {
  let diff;
  return retrieveUIDsFromDBForKey(rootkey)
    .then(uids => {
      diff = uids.diff(users_uids)
      let deletes = []
      diff.forEach(key => {
        deletes.push(firebase.database().ref(rootkey + "/" + key).remove())
      })
      return Promise.all(deletes)
    })
    .then(value => {
      return diff
    })
}

Обратите внимание, что для того, чтобы это работало, область действия переменной diff должнабыть увеличенным, как сделано выше.В качестве альтернативы вы можете добавить diff к аргументам, переданным Promise.all, так что вы получите доступ к diff в качестве обещанного значения:

function deleteUIDsFromDBForKey(rootkey, users_uids) {
  return retrieveUIDsFromDBForKey(rootkey)
    .then(uids => {
      let diff = uids.diff(users_uids)
      let deletes = []
      diff.forEach(key => {
        deletes.push(firebase.database().ref(rootkey + "/" + key).remove())
      })
      return Promise.all([diff, ...deletes])
    })
    .then(([diff]) => {
      return diff
    })
}

Не относится к вашему вопросу, но вы можете использовать mapвместо forEach с push:

  let deletes = diff.map(key => {
    return firebase.database().ref(rootkey + "/" + key).remove()
  })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...