简体   繁体   English

解析promises数组node.js

[英]Resolve array of promises node.js

I am new to promises, I am trying to use RSVP promises in Node.js with PostgreSQL and I am doing it wrong, most probably. 我是承诺的新手,我试图在Node.js中使用PostgreSQL中的RSVP承诺而且我做错了,最有可能。 Any suggestions on how to fix that or how to improve the code are appreciated. 任何关于如何解决或如何改进代码的建议都表示赞赏。

What I try to achieve is: after receiving data - process the data to create SQL update queries and when they are ready - execute them. 我试图实现的是:在接收数据之后 - 处理数据以创建SQL更新查询以及何时准备好 - 执行它们。 Data here is array of user ids. 这里的数据是用户ID数组。

What does not work: I get array of array of promises that doesn't resolve, I tried to resolve the array like so: 什么行不通:我获得了无法解析的数组的数组,我试图像这样解析数组:

var promise4all = RSVP.all(
  updateQueries.map((innerPromiseArray) => {
    return RSVP.all(innerPromiseArray);
  })
);

promise4all.then((promiseGroupResult) => {
     // doesn't get here
});

But it didn't work also. 但它也没有用。

The code: 编码:

1) The function 'update' that receives data and calls function 'promiseQuery' to process the data: 1)接收数据的函数'update'并调用函数'promiseQuery'来处理数据:

const RSVP = require('rsvp');

let db;

const update = (data) => {      
  let users = {
    items: data.user, // data to be updated in db - array of user ids
    item_type: 1,
    id: data.department
  }

  let updateQueries = [];

  // adding query promises to updateQueries
  updateQueries.push(promiseQuery(users.id, users.item_type, users.items));

  RSVP.all(updateQueries).then((results) => {

    /* here 'results' looks like that: 
       [ [ { query: 'INSERT INTO link_to_department (item_type, department, item) VALUES ($item_type, $department, $item)',
             values: [Object] },
          { query: 'DELETE FROM link_to_department WHERE department = $(department) AND item_type = $(item_type) AND item=$(item)',
             values: [Object] } ] ] 

    db update below fails with '[Empty or undefined query.]'*/

    db.tx((trx) => {
        let sqlUpdates = [];

        results.forEach((query) => {
            sqlUpdates.push(trx.none(query.query, query.values))
        })

        return trx.batch(sqlUpdates);
    }).then(() => {
        res.sendStatus(204);
    }).catch((err) => {
        console.log('error', err.message);
        // handle errors
    });
  });
};

2) The function 'promiseQuery' processes data (it compares received data and data in db to update db with the new data): 2)函数'promiseQuery'处理数据(它比较db中的接收数据和数据以使用新数据更新db):

const promiseQuery = (department_id, item_type, items) => {
    return new RSVP.Promise((resolve, reject) => {
        db.query('SELECT item FROM link_to_department WHERE department=' + department_id + ' AND item_type=' + item_type)
          .then((db_items) => {
            let promises = [];

            let itemsToBeRemoved = [];
            let itemsToBeAdded = [];

            /* here we have array of user ids we received: 'items' 
               and array of user ids from db: 'db_items' */

            // populating 'itemsToBeAdded' and 'itemsToBeRemoved' with user ids that need to added or removed:
            populateUpdateArray(items, db_items, itemsToBeAdded);
            populateUpdateArray(db_items, items, itemsToBeRemoved);

            let insert_query = 'INSERT INTO link_to_department (item_type, department, item) VALUES ($item_type, $department, $item)'
            let delete_query = 'DELETE FROM link_to_department WHERE department = $(department) AND item_type = $(item_type) AND item=$(item)';

            // creating update sql queries
            populateUpdateQuery(insert_query, itemsToBeAdded, department_id, item_type, promises);
            populateUpdateQuery(delete_query, itemsToBeRemoved, department_id, item_type, promises);

            RSVP.all(promises).then((results) => {
               /* here 'results' looks like this:
                  [ { query: 'INSERT INTO link_to_department (item_type, department, item) VALUES ($item_type, $department, $item)',
                      values: { item_type: 19, department: 1, item: '1' } },  
                    { query: 'DELETE FROM link_to_department WHERE department = $(department) AND item_type = $(item_type) AND item=$(item)',
                      values: { item_type: 19, department: 1, item: 1 } }] */

                return resolve(results);
            });

        }).catch(() => {
           reject();
    })
  });
};

3) That function 'populateUpdateArray' populates array of user ids that need to be updated (basically, received user ids should replace ids in the db - for that we check what ids we received are not in db and what ids in db are not in the received ids): 3)函数'populateUpdateArray'填充需要更新的用户ID数组(基本上,收到的用户id应该替换db中的id - 为此我们检查我们收到的id不在db中,db中的id不在收到的ids):

const populateUpdateArray = (array_0, array_1, updateArray) => {
   array_0.forEach((item) => {
      if (array_1.indexOf(item) === -1) {
        updateArray.push(item);
     }
  });
};

4) That function 'populateUpdateQuery' returns sql update queries: 4)函数'populateUpdateQuery'返回sql更新查询:

const populateUpdateQuery = (query, id_array, department_id, item_type, promises) => {
   return new RSVP.Promise((resolve, reject) => {
    id_array.forEach((item) => {
        let values = {
            item_type: item_type,
            department: department_id,
            item: item
        };

        promises.push({query, values});
    });

    resolve(promises);      
  });
};

Thank you! 谢谢!

EDIT: I changed the code to have only one db connection and I simplified the code a little. 编辑:我改变了代码只有一个数据库连接,我简化了一点代码。 I do not get any errors, but queries are not executed, still. 我没有收到任何错误,但仍然没有执行查询。 I think I am missing something basic here: 我想我错过了一些基本的东西:

const update = (data) => {
    let users = {
        items: data.user,
        item_type: 1,
        id: data.department
    }

    db.tx((tx) => {
        let updateQueries = [];

        updateQueries.push(promiseQuery(department.id, users.item_type, users.items, tx));

        RSVP.all(updateQueries).then((results) => {
            // results is array of array, so i flatten it
            let sqlUpdates = results.reduce((a, b) => { return a.concat(b); }, []);

            /* sqlUpdates here:   
             [ Promise {
                 _bitField: 0,
                 _fulfillmentHandler0: undefined,
                 _rejectionHandler0: undefined,
                 _promise0: undefined,
                 _receiver0: undefined } ]
            */

            return tx.batch(sqlUpdates);
        });
   }).then(() => {
       res.sendStatus(204);
   }).catch((err) => {
       console.log('error', err.message);
   });
};

const promiseQuery = (department_id, item_type, items, tx) => {
   return new RSVP.Promise((resolve, reject) => {
     tx.query('SELECT item FROM belongs_to_departments WHERE department=' + department_id + ' AND item_type=' + item_type)
        .then((db_items)=> {
            let queries = [];               
            let itemsToBeAdded = [];
            let insert_query = 'INSERT INTO belongs_to_departments (item_type, department, item) VALUES ($(item_type), $(department), $(item))';

            populateUpdateArray(items, db_items, itemsToBeAdded);
            populateUpdateQuery(insert_query, itemsToBeAdded, department_id, item_type, queries, tx);

            resolve(queries);
        }).catch(() => {
            reject();
        });
   });
};

const populateUpdateArray = (array_0, array_1, updateArray) => {
  array_0.forEach((item) => {
     if (array_1.indexOf(item) === -1) {
        updateArray.push(item);
     }
  });
};

const populateUpdateQuery = (query, id_array, department_id, item_type, queries, tx) => {
   id_array.forEach((item) => {
        let values = {
            item_type: item_type,
            department: department_id,
            item: item
        };

        queries.push(tx.none(query, values));
   });
};

Thanks to Vitaly for the help. 感谢Vitaly的帮助。 That worked for me: 这对我有用:

const update = data => {
    const users = {
        items: data.user,
        item_type: 1,
        id: data.department
    }

    db.tx(tx => {
        const updateQueries = [];

        updateQueries.push(promiseQuery(department.id, users.item_type, users.items, tx));

        RSVP.all(updateQueries).then(results => {
            // results is array of array, so i flatten it
            const sqlUpdates = results.reduce((a, b) => { return a.concat(b); }, []);                          

            return tx.batch(sqlUpdates);
        });
   }).then(() => {
       res.sendStatus(204);
   }).catch(err => {
       console.log('error', err.message);
   });
};

const promiseQuery = (department_id, item_type, items, tx) => {
   return new RSVP.Promise((resolve, reject) => {
     tx.query('SELECT item FROM belongs_to_departments WHERE department=' + department_id + ' AND item_type=' + item_type)
        .then(db_items => {
            const queries = [];               
            const itemsToBeAdded = [];
            const insert_query = 'INSERT INTO belongs_to_departments (item_type, department, item) VALUES ($(item_type), $(department), $(item))';

            populateUpdateArray(items, db_items, itemsToBeAdded);
            populateUpdateQuery(insert_query, itemsToBeAdded, department_id, item_type, queries, tx);

            resolve(queries);
        }).catch(() => {
            reject();
        });
   });
};

const populateUpdateArray = (array_0, array_1, updateArray) => {
  array_0.forEach((item) => {
     if (array_1.indexOf(item) === -1) {
        updateArray.push(item);
     }
  });
};

const populateUpdateQuery = (query, id_array, department_id, item_type, queries, tx) => {
   id_array.forEach(item => {
        const values = {
            item_type: item_type,
            department: department_id,
            item: item
        };

        queries.push(tx.none(query, values));
   });
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM