首页 > 解决方案 > Promise.all() 用于具有多个参数的承诺

问题描述

我正在使用来自服务器的数据动态构建条目列表。

每个条目都可以有一个父项。我想通过搜索它的 ID 从 DOM 中获取父名称。如果父条目已经在页面上,这一切都很好。如果不是,那么它当然会失败。

<div class="the_entry">
  <h4></h4>
  <select></select>
</div>
<script>
  const the_entry = document.querySelector('.the_entry');
  const parsed_data_from_server = [
    { entry_id: 0, entry_name: "zero", parent_id: 2},
    { entry_id: 1, entry_name: "one", parent_id: 2},
    { entry_id: 2, entry_name: "two", parent_id: 2},
  ];

  parsed_data_from_server.foreach((entry_from_the_server) => {
    // new div
    const new_entry = the_entry.cloneNode(true);
    the_entry.parentNode.insertBefore(new_entry, the_entry);
    new_entry.querySelector('h4').innerText = entry_from_the_server.entry_name;
    new_entry.querySelector('h4').id = entry_from_the_server.entry_id;
    // new option
    const new_option = document.createElement('option');
    new_entry.querySelector('select').appendChild(new_option);
    new_option.value = entry_from_the_server.parent_id;
    const name = document.querySelector(`[id="${entry_from_the_server.parent_id}"]`)
    new_option.innerText = name.innerText; // this will fail because no element with that id exists YET
  });
</script>

所以我想在处理完列表后使用 Promise 来创建选项元素。但要做到这一点,我需要传递 new_entry 和 entry_from_the_server。

这是我尝试过的...

let promises = [];
parsed_data_from_server.forEach((entry_from_the_server) => {
    // new div
    const new_entry = the_entry.cloneNode(true);
    the_entry.parentNode.insertBefore(new_entry, the_entry);
    new_entry.querySelector('h4').innerText = entry_from_the_server.entry_name;
    new_entry.querySelector('h4').id = entry_from_the_server.entry_id;
    // create a promise
    promises.push(new Promise((resolve, reject) => {
        resolve(new_entry, entry_from_the_server);
    }));
} );

Promise.all(promises).then((new_entries) => {
    new_entries.forEach((new_entry) => {
        // new option
        const new_option = document.createElement('option');
        new_entry.querySelector('select').appendChild(new_option);

        // where do I get entry_from_the_server from?!
        new_option.value = entry_from_the_server.parent_id;
        new_option.innerText = document.querySelector(`[id="${entry_from_the_server.parent_id}"]`).innerText;
    })
} );

一切都很好,直到最后一部分......我从哪里得到第二个论点?这可能吗?

标签: javascriptes6-promise

解决方案


该函数resolve采用单个参数,如果您传递多个参数,则第一个将被视为将被忽略,其余的将被忽略。在您的情况下,您可以发送一个对象:

promises.push(new Promise((resolve, reject) => {
     resolve({new_entry, entry_from_the_server});
}));

在解析的值中,您将获得一个数组,第一个索引将具有new_entry,第二个将具有entry_from_the_server

Promise.all(promises).then((new_entries) => {
    //using destructuring
    new_entries.forEach(({new_entry, entry_from_the_server}) => {
        // new option
        const new_option = document.createElement('option');

        new_entry.querySelector('select').appendChild(new_option);

        new_option.value = entry_from_the_server.parent_id;
        new_option.innerText = document.querySelector(`[id="${entry_from_the_server.parent_id}"]`).innerText;
    })
} );

推荐阅读