【问题标题】:How does one access, process and pass along response data outside of the request?如何在请求之外访问、处理和传递响应数据?
【发布时间】:2021-10-07 01:44:07
【问题描述】:

在下面的sn-p中,我希望能够在请求函数之外访问locationArray,我明白在下面的代码中它为什么不起作用,但是,我尝试了许多不同的方法来访问大批。我尝试过使用 Promise、回调函数等,但是,它们似乎都不起作用。

关于如何做到这一点的任何其他想法?即使对我尝试过的方法持开放态度,因为此时一切都值得一试。

request(process.env.RESOURCE_SHEET, (error, response, html) => {
   var locationArray = new Array
      if(!error && response.statusCode == 200) {
  
      const $ = cheerio.load(html);
              
       $("h3").each((i, lle) => {
        const location = $(lle).text();
  
        if(location.includes("Kansas")) return;
        if(location.includes("In Stock")) {
           var level = location + " ✅";
        } else {
           var level = location + " ❌";
        }
        locationArray.push(level);
        });
       } 
       console.log(locationArray) // Output 1: [level1,level2,level3,leveletc]
});
console.log(locationArray) // Output 2: []

【问题讨论】:

  • 请求是异步的,因此您不能访问请求之外的变量,除非您使用事件或其他在请求之后发生的异步活动。您可以将响应包装在 Promise 中,但传递给 Promise 的函数只会在异步活动完成时解析或拒绝,前提是您编写正确。

标签: javascript asynchronous callback request es6-promise


【解决方案1】:

人们不仅可以考虑基于Promise 的方法,正如已经建议的那样,还可以考虑代码重构,将不同的关注点分离到任务中,并将后者实现为可以馈送/传递给承诺链的函数。作为一个优势,重构可以用人类可读的代码来回报,这也可能更容易维护......

function createRequest(src) {
  return new Promise((resolve, reject) => {

    request(src, (error, response, html) => {
      if (!error && response.statusCode === 200) {

        resolve(html);
      } else {
        reject({ error, response });
      }
    });
  };
}
function handleFailedRequest(reason) {
  const { error, response } = reason;
  // proceed with failure handling based on
  // either request data `error` and/or `response`.
}

function createLocationArray(html) {
  const locationArray = [];
  const $ = cheerio.load(html);

  $('h3').each((i, lle) => {
    const location = $(lle).text();
    if (!location.includes('Kansas')) {

      const isInStock = location.includes('In Stock');
      locationArray.push(
        `${ location } ${ isInStock && '✅' || '❌' }`
      );
    }
  });
  return locationArray;
}
function processLocationArray(array) {
  console.log('locationArray ... ', array);
}

const promisedResponse = createRequest(process.env.RESOURCE_SHEET);

promisedResponse
  .then(createLocationArray)
  .then(processLocationArray)
  .catch(handleFailedRequest);

【讨论】:

    【解决方案2】:

    @StackSlave 是对的,它只需要一个 Promise,我相信我在第一次尝试使用 Promise 解决它时弄乱了语法,但这似乎有效。

    const promise = new Promise((resolve,reject) => {
     request(process.env.RESOURCE_SHEET, (error, response, html) => {
       var locationArray = new Array
          if(!error && response.statusCode == 200) {
      
          const $ = cheerio.load(html);
                  
           $("h3").each((i, lle) => {
            const location = $(lle).text();
      
            if(location.includes("Kansas")) return;
            if(location.includes("In Stock")) {
               var level = location + " ✅";
            } else {
               var level = location + " ❌";
            }
            locationArray.push(level);
            resolve(locationArray);
            });
           } 
           console.log(locationArray) // Output 1: [level1,level2,level3,leveletc]
     });
    });
    promise.then(array => {
      console.log(array);
    });
    

    【讨论】:

    • 人们不仅可以考虑基于Promise 的方法,正如它已经建议的那样,还可以考虑代码重构,将不同的关注点分成任务并将后者实现为可以馈送/传递的函数到承诺链。作为一个优势,重构可以用人类可读的代码来回报,这也可能更容易维护......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 2013-06-22
    • 2021-05-31
    • 2011-02-23
    • 1970-01-01
    • 2020-04-12
    • 1970-01-01
    相关资源
    最近更新 更多