Как вернуть данные после разрешения нескольких обещаний одновременно? - PullRequest
0 голосов
/ 18 октября 2018

Здесь я создал объект данных

const data = new Object();

Затем я вызываю несколько API параллельно

datamuse.request(`words?ml=${text}`)
    .then((list) => {
      data.ml = list;
    })
    .catch((error) => {
      console.log(error);
    });

  datamuse.request(`words?sp=${text}`)
    .then((list) => {
      data.sp = list;
    })
    .catch((error) => {
      console.log(error);
    });

  datamuse.request(`words?rel_trg=${text}`)
    .then((list) => {
      data.rel = list;
    })
    .catch((error) => {
      console.log(error);
    });

  datamuse.request(`sug?s=${text}`)
    .then((list) => {
      data.sug = list;
    })
    .catch((error) => {
      console.log(error);
    });

  datamuse.request(`words?sl=${text}`)
    .then((list) => {
      data.sl = list;
    })
    .catch((error) => {
      console.log(error);
    });

И, наконец, возвращаю данные:

return data;

И данные возвращаются как undefined.Я знаю, что выполняю асинхронные операции одновременно.

Но я не хочу использовать генератор функций в этом случае, потому что он слишком медленный.

Может кто-нибудь помочь мне получить эти значенияв данных, а затем вернуть его?

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Promise.resolve это путь сюда.Кроме того, я бы предложил отделить логику от данных.

function getResult(where) {
  const result = {}
  return Promise.all(
    Object
      .entries(where)
      .map(([key, path]) => datamuse.request(path).then(list => result[key] = list))
  )
  .then(() => result)
}

function createMapForText(text) {
  return {
    ml: `words?ml=${text}`,
    sp: `words?sp=${text}`,
    rel: `words?rel_trg=${text}`,
    sug: `sug?s=${text}`,
    sl: `words?sl=${text}`
  }
}

// ----- Testing -----

// Fake `datamuse` for testing purposes only
const datamuse = {
  request: (path) => Promise.resolve('hello')
}

getResult(
  createMapForText('hello')
).then(console.log.bind(console))
0 голосов
/ 18 октября 2018

Что-то вроде

Promise.all([
  datamuse.request(`words?ml=${text}`),
  datamuse.request(`words?sp=${text}`),
  datamuse.request(`words?rel_trg=${text}`),
  datamuse.request(`sug?s=${text}`),
  datamuse.request(`words?sl=${text}`),
]).then(([
  ml,
  sp,
  rel,
  s,
  sl
]) => {
  const data = {
    ml,
    sp,
    rel,
    s,
    sl,
  };
}).catch((err) => {
  // Deal with error
});

Или даже лучше Вы должны добавить что-то для различия слов и слов, я позволю вам разобраться:)

const elems = [
  'ml',
  'sp',
  'rel_trg',
  's',
  'sl',
];

Promise.all(elems.map(x => datamuse.request(`words?${x}=${text}`))
    .then((rets) => {
      const data = elems.reduce((tmp, x, xi) => ({
         ...tmp,

         [x]: rets[xi];
      }), {});
    }).catch((err) => {
      // Deal with error
    });




Хорошо, вот одно из возможных решений для вашей words и sug проблемы

const elems = [{
  acronym: 'ml',
  req: 'words',
}, {
  acronym: 'sp',
  req: 'words',
}, {
  acronym: 'rel_trg',
  req: 'words',
}, {
  acronym: 's',
  req: 'sug',
}, {
  acronym: 'sl',
  req: 'words',
}];

Promise.all(elems.map(({
      acronym,
      req,
    }) => datamuse.request(`${req}?${acronym}=${text}`))
    .then((rets) => {
      const data = elems.reduce((tmp, {
        acronym,
      }, xi) => ({
        ...tmp,

        [acronym]: rets[xi];
      }), {});
    }).catch((err) => {
      // Deal with error
    });
...