Обещания в JS: использование Ax ios для записи в mongoDB - PullRequest
0 голосов
/ 07 января 2020

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

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

В частности, мне нужна помощь о том, как я могу передать результат выполненного обещания в моем коде. В приведенном ниже коде я извлекаю файл JSON из API-интерфейса starwars и хочу записать его в коллекцию атласа mongodb.

Я использую ax ios .get, который возвращает обещание. Затем я разрешаю его, используя .then, а затем использую insertOne для коллекций mongoDB.

На внешнем интерфейсе, например, в React, он работает как положено, где вы используете setState для изменения состояния с помощью setState внутри .then функция. Я не понимаю, почему это не работает в бэкэнде.

Не могли бы вы сказать мне, что мне нужно изменить, чтобы я мог заставить его писать в атласе mongoDB?

var axios = require("axios");
const MongoClient = require("mongodb").MongoClient;
var db;

const getData = () => {
  return axios
    .get("https://swapi.co/api/people/1")
    .then(response => {
      if (!response.data) throw Error("No data found.");
         console.log(JSON.stringify(response.data))  **//This returns the data as expected.**
         return JSON.stringify(response.data);
    })
    .catch(error => {
      console.log(error);
      throw error;
    });
};

console.log(getData()); **// This returns {Promise <pending>}**


const client = new MongoClient(process.env.MONGODB_URL, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

// Connect to database and insert default users into users collection
client.connect(err => {

  console.log("Connected successfully to database");

  let d = {
    name: "Luke Skywalker",
    height: "172",
    mass: "77",
    hair_color: "blond",
    skin_color: "fair",
    eye_color: "blue"
  };



  db = client.db(process.env.DB_NAME);
  db.collection("macroData").insertOne(d);  //this works
  db.collection("macroData").insertOne(getData); // this doesn't work as it still appears to  be a promise
});

Ответы [ 2 ]

0 голосов
/ 18 января 2020

Ваш вызов mongodb должен быть в пределах обещания топора ios, чтобы разрешенное обещание могло использоваться для подачи в вашу базу данных. Это то, что задержало меня на некоторое время ...

Код ниже предназначен для комментария Ника, я не смог опубликовать код в комментарии, так как он был слишком длинным. У вас должна быть база данных с именем test или подходящее имя здесь let datab = client.db('test'), я думаю, что это происходит по умолчанию при создании атласа mongodb. если вы измените свой логин и пароль в mongourl, вам следует набрать go. Надеюсь, это поможет. Это создает запись starwars под test.starWarsData .. hope t

let axios = require("axios");
let MongoClient = require("mongodb").MongoClient;
let mongoParams = { useNewUrlParser: true, useUnifiedTopology: true };

let mongoUrl =
  "mongodb+srv://user:password@cluster0-hnc4i.azure.mongodb.net/test";
//try feeding just the object e, and see if it works, in case your axios error catching is not great.
let e = {
  a: "this is a",
  b: "this is b",
  c: "this is c",
  d: "this is d"
};

let newUrl = "https://swapi.co/api/people/1";

console.log(newUrl);

let client = new MongoClient(mongoUrl, mongoParams);

client.connect(err => {
  if (err) {
    console.log(err.message);
    throw new Error("failed to connect");
  }

  let datab = client.db("test");
  console.log("db connected");

  try {
    axios.get(newUrl).then(res => {
      try {
        datab.collection("starWarsData").insertOne(res.data);
        console.log("insert succeeded");
      } catch (err) {
        console.log("insert failed");
        console.log(err.message);
      }
    });
  } catch (err) {
    throw Error("axios get did not work");
  }
});
0 голосов
/ 07 января 2020

getData() возвращает Обещание, как вы хорошо знаете, поэтому вам нужно дождаться выполнения этого обещания. Простой подход - выполнить вставку после того, как данные станут доступны:

  client.connect(err => {
    // ...
    getData().then(data => {
      db.collection('macroData').insertOne(data)
    })
  })

Или, если вы можете использовать async / await:

client.connect(async err => {
  // ...
  const data = await getData()

  db.collection('macroData').insertOne(data)
})
...