Создайте массив объектов, где некоторые поля нуждаются в удаленных данных - PullRequest
2 голосов
/ 26 февраля 2020

Я пытаюсь создать массив объектов, где некоторые поля нуждаются в удаленных данных. Я написал следующее доказательство концепции, и оно работает, но параллельные массивы кажутся грязными. Будем благодарны за предложения о том, что объединяет ключи и обещания:

async function p1(x) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`p1-${x}`);
    }, 250);
  });
}

async function p2(x) {
  return new Promise((resolve) => {
    setTimeout( () => {
      resolve(`p2-${x}`);
    }, 250);
  });
}

async function t(n) {
  return { a: await p1(n), b: await p2(n), c: n };
}

async function r() {
  const keys = [];
  const values = [];
  for (let i = 0; i < 2; i++) {
    const key = `k${i}`
    keys.push(key);
    values.push(t(key));
  }
  const x = await Promise.all(values);
  const results = {};
  for (let i = 0; i < keys.length; i++) {
    results[keys[i]] = x[i];
  }
  return results;
}

(async () => {
  const answers = await r();
  console.log('answers', answers);
})().catch((e) => {
  console.log(e);
});

Ответы [ 3 ]

1 голос
/ 26 февраля 2020

Нет необходимости кэшировать ключи и значения в отдельном l oop. Вы можете построить объект результатов на go:

async function p1(x) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`p1-${x}`);
    }, 250);
  });
}

async function p2(x) {
  return new Promise((resolve) => {
    setTimeout( () => {
      resolve(`p2-${x}`);
    }, 250);
  });
}

async function t(n) {
  return { a: await p1(n), b: await p2(n), c: n };
}

async function r() {
  let results = {};
  for (let i = 0; i < 2; i++) {
    const key = `k${i}`
    results[key] = await t(key);
  }
  return results;
}

(async () => {
  const answers = await r();
  console.log('answers', answers);
})().catch((e) => {
  console.log(e);
});
1 голос
/ 26 февраля 2020

Я думаю, что мой подход к r будет следующим:

async function r() {
  const results = {};
  const promises = [];
  for (let i = 0; i < 2; i++) {
    const key = `k${i}`
    promises.push(t(key).then(value => results[key] = value));
  }
  await Promise.all(promises);
  return results;
}

Обратите внимание, как results заполняется в l oop (асинхронно), мы используем только promises, поэтому мы знаем, когда все сделано (или, конечно, что-то не получилось). При этом ключ и значение хранятся в теле l oop.

Живая копия:

// No need for p1 and p2 to be `asycn` since they don't
// use `await`; I'm guessing your real functions do
// (and don't use `new Promise`)

/*async*/ function p1(x) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`p1-${x}`);
    }, 250);
  });
}

/*async*/ function p2(x) {
  return new Promise((resolve) => {
    setTimeout( () => {
      resolve(`p2-${x}`);
    }, 250);
  });
}

async function t(n) {
  return { a: await p1(n), b: await p2(n), c: n };
}

async function r() {
  const results = {};
  const promises = [];
  for (let i = 0; i < 2; i++) {
    const key = `k${i}`
    promises.push(t(key).then(value => results[key] = value));
  }
  await Promise.all(promises);
  return results;
}

(async () => {
  const answers = await r();
  console.log('answers', answers);
})().catch((e) => {
  console.log(e);
});
.as-console-wrapper {
    max-height: 100% !important;
}
1 голос
/ 26 февраля 2020

Этот конечный автомат также работает:

async function p1(x) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`p1-${x}`);
    }, 250);
  });
}

async function p2(x) {
  return new Promise((resolve) => {
    setTimeout( () => {
      resolve(`p2-${x}`);
    }, 250);
  });
}

async function t(n) {
  return { a: await p1(n), b: await p2(n), c: n };
}

async function r() {
  const results = {}
  for (let i = 0; i < 2; i++) {
   const key = `k${i}`
   results[key] = await t(key)
  }
  return results;
}

(async () => {
  const answers = await r();
  console.log('answers', answers);
})().catch((e) => {
  console.log(e);
});

Этот тоже:

  async function p1(x) {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve(`p1-${x}`);
        }, 250);
      });
    }

    async function p2(x) {
      return new Promise((resolve) => {
        setTimeout( () => {
          resolve(`p2-${x}`);
        }, 250);
      });
    }

    async function t(n) {
      return { a: await p1(n), b: await p2(n), c: n };
    }

    async function r(questions) {
      return (await Promise.all(
        questions.map(async i => ({[`k${i}`]: await t(`k${i}`)})
        ))).reduce((prev, curr) => ({...prev, ...curr}), {})    
    }

    (async () => {
      const answers = await r(['1', '2']);
      console.log('answers', answers);
    })().catch((e) => {
      console.log(e);
    });

Второй вариант может быть реорганизован лучше, но я не знаю вашего возможного варианта использования. Он использует без переменных и без циклов . Вот такой подход я бы go использовал.

...