Javascript 如何使用json响应创建另一个URL。Nodejs

Javascript 如何使用json响应创建另一个URL。Nodejs,javascript,node.js,mongodb,parsing,promise,Javascript,Node.js,Mongodb,Parsing,Promise,我有一个问题,代码如下: 问题是: 如何将responsepromiseGetCitiesData中的每一行发送到promiseGetInformationDataPerCity 我可以在一个async中完成它吗?每个都可以运行吗 现在,我创建了多个Promise函数。一个通用函数,该函数启动程序-getDataAndCloseDb() 我还使用了async.each调用带有数组参数的promise函数-locationArray 现在,我想将json响应中的每一行发送到下一个承诺函数(crea

我有一个问题,代码如下:

问题是:


  • 如何将response
    promiseGetCitiesData
    中的每一行发送到
    promiseGetInformationDataPerCity
  • 我可以在一个
    async中完成它吗?每个
    都可以运行吗
  • 现在,我创建了多个Promise函数。一个通用函数,该函数启动程序-
    getDataAndCloseDb()

    我还使用了
    async.each
    调用带有数组参数的promise函数-
    locationArray

    现在,我想将json响应中的每一行发送到下一个承诺函数(creategetURL),并收集一般响应

    const MongoClient = require("mongodb").MongoClient;
        const request = require("request");
        const async = require("async");
    
        var locationsArray = [
          'location1',
          'location2',
          'location3'
        ];
    
        function promiseConnectToDatabase(urldb) {
          return new Promise(function(resolve, reject) {
            MongoClient.connect(urldb, (err, db) => {
              if (err) {
                console.log("MongoDb connection error.");
                reject(err);
              }
              console.log("Connected to MongoDb.");
              resolve(db);
            });
          });
        }
    
        function promiseGetCitiesData(location) {
          return new Promise(function(resolve, reject) {
            request({
              url: `https://example.com/${location}`,
              json: true
            }, (error, response, body) => {
              if (error) {
                console.log("Error connection to url.");
                reject();
              }
              console.log("location: " + location);
              console.log({location: location, cities: body.result.cities});
              resolve({location: location, cities: body.result.cities});
            });
          });
        }
        /*
        Example response from promiseGetCitiesData:
    
        Location: location1
        { location: 'location1',
          cities: 
           [ 'information1',
             'information2',
             'information3',
             'information4'' ] }
    
        */
    
        function promiseGetInformationDataPerCity(location, cities) {
          return new Promise(function(resolve, reject) {
            request({
              url: `https://example.com/${location}/${cities}`,
              //f.e https://example.com/location1/information1 etc.
              json: true
            }, (error, response, information) => {
              if (error) {
                console.log("Error connection to url.");
                reject();
              }
              console.log(information);
              resolve(information);
            });
          });
        }
    
        function promiseSaveDataToDatabase(db, body) {
          return new Promise(function(resolve, reject) {
            db.collection("testlocation").insert(body, function(dbError) {
              if (dbError) {
                reject(dbError);
              }
              resolve()
            });
          });
        }
    
        function promiseDisconnectDatabase(db) {
          return new Promise(function(resolve, reject) {
            db.close((err) => {
              if (err) {
                console.log("MongoDb disconnect error.");
                reject(err);
              }
              console.log("MongoDb disconnected.");
              resolve();
            });
          });
        }
    
        function promiseProvideDataFromEach(locationsArray, db) {
          return new Promise(function(resolve, reject) {
            async.each(locationsArray, function(loc, locProcessedCb) {
              promiseGetcitiesData(loc).then(function(resultscities) {
                promiseGetInformationDataPerCity(loc, resultscities).then(function(resultDetails) {
                    promiseSaveDataToDatabase(db, resultDetails).then(function() {});
                locProcessedCb();
                });
              });
            }, function(err) {
              if (err) {
                locProcessedCb(err);
                reject(err);
              }
              console.log("All locations have been processed.");
              resolve();
            });
          });
        }
    
        function getDataAndCloseDb() {
          return new Promise(function(resolve, reject) {
            promiseConnectToDatabase("mongodb://127.0.0.1:27017/testApp").then(function(db) {
              promiseProvideDataFromEach(locationsArray, db).then(function() {
                promiseDisconnectDatabase(db).then(function() {});
              });
            });
          });
        }
    
        getDataAndCloseDb();
    

    你可以这样做。这是一个更简单的代码,但我认为您可以将其映射到当前代码

    const Promise = require('bluebird')
    
    const cities = ['citya', 'cityb', 'cityc']
    
    function resolveCities() {
      return new Promise(function(resolve, reject) {
        resolve(cities)
      })
    }
    
    function logCity(city) {
      console.log('city ', city)
    }
    
    return resolveCities() 
    .then(function(cities) {
      return Promise.mapSeries(cities, function(city) {
        logCity(city);
      });
    })
    

    我认为这比问题中的代码看起来要简单得多。特别是,
    新承诺(…)
    可以通过以下方式完全避免:

    • 使用
      require('async-request')
      而不是
      require('request')
    • 允许MongoDb方法返回承诺,如果不传递回调,许多方法都会返回承诺

    • 通过使用
      Promise.all(array.map(…)
      模式,对
      require('async')
      的需求消失了
    • -提供了一个非常有用的可重复使用处理器实用程序
    • 记住从每个.then()回调返回一个承诺/值,该回调本身是异步的,并且/或者应该传递数据
    经过一些猜测,我想你想要这样的东西:

    const MongoClient = require('mongodb').MongoClient;
    const request = require('async-request'); // just like `request()` but returns a promise
    
    var locationsArray = [
        'location1',
        'location2',
        'location3'
    ];
    
    function promiseGetCitiesData(loc) {
        return request({
            url: `https://example.com/${loc}`,
            json: true
        }).then(body => body.result.cities);
    }
    
    function promiseGetInformationDataPerCity(loc, cities) {
        return Promise.all(cities.map(city => {
            return request({
                'url': `https://example.com/${loc}/${city}`,
                'json': true
            }).then(cityInfo => ({ 'name':city, 'info':cityInfo }));
        }));
    }
    
    function promiseProvideDataFromEach(locationsArray, db) {
        return Promise.all(locationsArray.map(loc => {
            return promiseGetCitiesData(loc)
            .then(cities => promiseGetInformationDataPerCity(loc, cities)
            .then(citiesWithCityInfo => ({ 'location':loc, 'cities':citiesWithCityInfo }));
        }))
        .then(resultDetails => db.collection('testlocation').insertMany(resultDetails));
    }
    
    // disposer utility - credit: https://stackoverflow.com/a/28915678/3478010
    function withDb(work) {
        var _db;
        return MongoClient.connect("mongodb://127.0.0.1:27017/testApp")
        .then((db) => {
            _db = db; // keep reference 
            return work(db); // perform work on db
        }).finally(() => {
            if (_db)
                _db.close();
        });
    }
    
    withDb(db => promiseProvideDataFromEach(locationsArray, db))
    .then(() => {
        // connection released here
    });
    

    猜测主要集中在
    db.collection('testlocation').insertMany(resultDetails)
    中要插入的内容。问题中的代码只提供了一个线索。我的尝试似乎合理,但可能不是你想要的。请准备在
    promiseProvideDataFromEach()
    promiseGetInformation Datapercity()

    中进行一些更改,我很难理解您想要做什么。您可以检查
    Promise。所有
    模式都可以满足您的要求。我想将响应从
    promiseGetCitiesData{…“location1”、“location2”…等
    发送到
    promiseGetInformationDataPerCity
    (如代码中的注释)。最好的解决方案是每行发送:1。发送位置请求,获取包含信息的json。2.将响应json中的每一行发送到promiseGetCitiesData,收集响应,保存到数据库。3.再次发送位置2等请求。@Antonio Narkevich您是node js、java脚本技术的专家。您能检查一下我的问题吗?我在
    promiseGetInformationDataPerCity(位置,城市)
    中有点困惑,url是按
    https://example.com/${location}/${cities}
    <代码>位置
    只要是字符串就可以了。但是
    cities
    (复数)是由
    promiseGetcitiesData()
    交付的数组。那么应该将
    cities
    合并成一个字符串,还是应该是
    https://example.com/${location}/${city}/
    在某种循环中?@Roamer-1888感谢您的回复。就像我描述的那样。在调用promiseGetCitiesData之后,我得到了“promiseGetCitiesData的示例响应”(json带有“information1”、“information2”等字样)“我想发送到:promiseGetInformationDataPerCity,并使用它来创建URL地址,如:。。。及。你安装蓝鸟模块了吗?在我这方面工作正常。是的,bluebird模块已经安装。但是我不能解析每一行来调用另一个promise函数。所有这些都在一起-应该异步工作。第一次调用promiseGetCitiesData,每条线路都应该一个接一个地发送给另一个promiseGetCitiesData,然后第二次调用PromiseCitiesData。好的,为了更好地了解您的问题,您想根据一些数据向promiseGetCitiesData发送多个调用吗?请给我一个示例,说明您希望在每个请求中发送给
    promiseGetCitiesData
    的数据。如果您希望逐个执行,则必须使用同步流而不是异步流。如我的说明所示。调用
    promiseGetCitiesData
    后,我得到了“promiseGetCitiesData的示例响应”(json带有“information1”、“information2”等字样)“我想发送到:
    promiseGetInformationDataPerCity
    ,并使用它来创建URL地址,如:
    https://example.com/location1/information1, https://example.com/location1/information2... https://example.com/location1/informationN
    https://example.com/location2/information1... https://example.com/location2/informationN... https://example.com/locationN/informationN.
    谢谢。我仍然对所有这些都有问题:
    then(cityInfo=>{'name':city,'info':cityInfo})-错误-
    意外“:“令牌”
    。如果我删除到,f.e.:
    然后(cityInfo=>body.result);
    -错误是:
    “arequest=async(url,options)”
    。然后(citiesWithCityInfo=>{'location','cities':citiesWithCityInfo});
    。好的,缺少()在json响应中。但现在我仍然有
    async请求/src/main.js:141 arequest=async(url,options)=>{
    错误。是的,我的错,这些都是“.我忘记了括号!答案已编辑。
    promiseGetCitiesData()
    也包含错误。已编辑。我也做了更改(在promiseGetCitiesData上)但是我仍然有错误,就像我最后的评论:
    async request/src/main.js:141 arequest=async(url,options)=>{Unexpected token(.
    但是没有关于行的信息。奇怪的错误。就像来自async request包。