Узел JS возвращает значения из функции - PullRequest
0 голосов
/ 01 октября 2018

Я живу в мире PHP, но я пытаюсь создать REST Api, используя Node.

Я застрял весь день, пытаясь вернуть массив результатов из цикла for.В основном я передаю массив field_name: field_value.Я хочу вставить результат обновления в массив для возврата.Я могу получить его, чтобы войти в консоль, но не дальше.

Вот пример сообщения json

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

Вот функция и цикл

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 }));

Я изучал асинхронные, но не уверен, что лучший маршрут здесь.Любая помощь будет отличной!

Ответы [ 2 ]

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

Решение Вы хотите:

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
    });
});

или параллельно:

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
    });
});

Правильное решение

Как я понимаю Вы хотите получать данные постов и обновлять записи в таблице пользователей.

Так почему бы просто не сделать это за один раз?запрос?

Попробуйте следующим образом:

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'
    });
  }
});

Но лучше подумайте об использовании ORM, то есть Sequelize для функций безопасности, проверки и т. Д., Которые облегчают жизнь разработчика.

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

Вы можете собрать все результаты в массив и отправить его, когда размер массива равен размеру ключа:

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
      }));
    }
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...