简体   繁体   English

Node JS从函数返回值

[英]Node js returning values from function

I live in the PHP world but I am attempting to build out a REST Api using Node. 我生活在PHP世界中,但是我正在尝试使用Node构建REST Api。

I have been stuck all day of trying to return an array of results from a for loop. 我整日忙于尝试从for循环返回结果数组。 Basically I am passing an array of field_name:field_value. 基本上,我传递的是field_name:field_value的数组。 I want to push the result from the update into an array to return. 我想将更新的结果推送到数组中以返回。 I can get it to log in the console but no further. 我可以将其登录到控制台,但没有其他内容。

Here is a sample post json data 这是一个示例发布json数据

{
    "first_name":"Jeff",
    "phone":"4855555555"
}

Here is the function and loop 这是功能和循环

function UpdateKey(user_id, key, value, cb) {
    connection.query('UPDATE users SET ' + key + ' = ? WHERE id = ? LIMIT 1', [value, user_id], function(err, results) {
    if (err) {
        callback = key + " update failed.";
    } else {
        callback = key + " was updated.";
    }
    cb(callback);

  });
}    

for (myKey in post_data) {
  UpdateKey(user_id, myKey, post_data[myKey], function(id) {
    console.log(id);
  });
}

res.send(JSON.stringify({ "status": 200, "error": "", "response": my_results_here }));

I have been researching async but not sure the best route here. 我一直在研究异步,但不确定这里的最佳路由。 Any help would be great! 任何帮助将是巨大的!

You could collect all results in an array and send that when the arrays size equals the keys size: 您可以将所有结果收集到数组中,然后在数组大小等于键大小时发送该结果:

const keys = Object.keys(post_data);
const response = [];

for(const myKey of keys) {
  UpdateKey(user_id, myKey, post_data[myKey], function(id) {
    response.push(id);
    if(keys.length === response.length) {
      res.send(JSON.stringify({ 
       status: 200, 
       error: "", 
       response
      }));
    }
  });
}

The solution You want: 您想要的解决方案:

const updateUserField = (userId, field, value) => {
  return Promise((resolve) => {
    const query = 'UPDATE users SET ' + field + ' = ? WHERE id = ?';
    const data = [value, userId];
    connection.query(query, data, (error) => {
      if (error) return resolve(field + ' update failed');
      resolve(field + ' was updated');
    });
  });
};


router.post('/user/:id', async (req, res) => {
    const userId = req.params.id;
    const data = req.body;

    const response = [];
    for (const field in data) {
      response.push(
        await updateUserField(userId, field, data[field])
      );
    }

    res.status(200).send({
      response
    });
});


or in parallel: 或并行:

router.post('/user/:id', async (req, res) => {
    const userId = req.params.id;
    const data = req.body;

    const response = await Promise.all(
      Object
        .keys(data)
        .map(field => updateUserField(userId, field, data[field]))
    );

    res.status(200).send({
      response
    });
});



Correct solution 正确的解决方案

As I understand You want to get post data and update record in users table. 据我了解,您想获取用户表中的帖子数据并更新记录。

So why not just do it in one query? 那么,为什么不只在一个查询中这样做呢?

Try this way: 尝试这种方式:

const updateUser = (userId, data) => {
  return Promise((resolve, reject) => {
    const query = 'UPDATE users SET ? WHERE id = ?';
    connection.query(query, [data, userId], (error) => {
      if (error) return reject(error);
      resolve();
    });
  });
};

router.post('/user/:id', async (req, res) => {
  try {
    const userId = req.params.id;
    const data = req.body;
    await updateUser(userId, data);
    res.status(200).send({
      message: 'User account successfully updated'
    })
  }
  catch (error) {
    console.error(error);
    res.status(500).send({
      message: 'Failed update user account'
    });
  }
});



But better think about using ORM ie Sequelize for security, validation and etc features that eases dev's life. 但是最好考虑使用ORM,即Sequelize的安全性,验证等功能,这些功能可以简化开发人员的工作。

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

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