首页 > 解决方案 > API 调用和回调

问题描述

我正在尝试创建一个进行 2 个 API 调用的路由,第二个取决于第一个的结果,并且仅在满足某些条件时才需要调用。以下是我遇到的问题。

  1. 无论如何,finalCheck 函数似乎在 forEach 之前被调用?即使包裹在 if 语句中
  2. 计数器和 userNamesAvailable 在它们分配的范围之外不可用。
  3. 我相信有更好的方法可以做到这一点,并且会喜欢任何相关的建议。

    router.post('/namecheck', async function(req, res, next) {   
      var name = req.body.name;
      var counter = 0
      var domains = []
      var userNamesAvailable = []
      var dotcom = true
      var answer = ''
    
    getDomains(checkDomains)
    
    // Check domain availabilty
    function getDomains (callback) {
      var url='https://api.ote-godaddy.com/v1/domains/available?checkType=FAST'
      Unirest.post(url)
        .headers({
          "Authorization" : "sso-key ",
          "Content-Type": "application/json"
        })
        .send(
          [
            name + '.com',
            name + '.net',
            name + '.org'
          ]
        )
        .end(function(response) { 
          domains=response.body.domains
          console.log(domains)
          callback(domains)
        })
    
    }
     function checkDomains(domains) {
       var d = 0
    
    //If no data is returned send error
    if(!domains) 
    {
      console.log("No data returned")
      return next("No data returned")
    } else {
      //Check how many domains are unavailable
      for(var i=0; i < domains.length; i++) {
        if(domains[i].available == false){
          d = d + 1
          //Flag if the .com is available
          if(domains[i].domain == name + '.com') {
            dotcom = false
          }
        }
      }
    
      if (d >2) {
        console.log("d is greater than 1")
        answer = 'no'
      //If 2 domains are available and one is .com continue
      } else if (d>1 && dotcom =='false') {
        answer = 'no'
      }
    }
    getUsernames(finalCheck)
    }
    
    function getUsernames(callback){
      // Social Sites to Check
      var sitenames = [ 
        'facebook',
        'twitter',
        'instagram',
        'youtube',
        'slack',
        'blogger'
      ]
    
      // Check Usename availabitliy
      let i = 0
      sitenames.forEach(sitename => {
    
      Unirest.post('https://api.namechk.com/services/check.json')
      .headers({
        'AUTHORIZATION': 'Bearer ',
        'Accept': 'application/vnd.api.v1+json',
      }).send({
        'site': sitename, username: name,
      }).end(function(response) { 
        if(response.body.available == false){
          counter ++
        } else {
          userNamesAvailable.push(response.body)
        }
      });
      i++
    });
    console.log(counter)
    console.log(userNamesAvailable)
    if(i == sitenames.length){
      callback(counter, dotcom)
     }
    }
    
    function finalCheck(counter, dotcom) {
      console.log('Start finalCheck')
      console.log(counter)
      console.log(dotcom)
        //Final Check for is a name is a go or not
        //If one social site is not available and the 
        if(counter == 1 && dotcom =='true') {
          console.log(5-counter + ' social sites available')
          res.send("yes");
        } else {
          res.send("no")
        }
      }
     })
    

标签: javascriptnode.jsapiexpresscallback

解决方案


按照这个问题的答案。您应该可以使用Promise.

您只需更改功能getUsernames

  function getUsernames(callback) {
    // Social Sites to Check
    var sitenames = [
      'facebook',
      'twitter',
      'instagram',
      'youtube',
      'slack',
      'blogger'
    ];

    // Check Usename availabitliy
    let requests = sitenames.map((sitename) => {
      return new Promise((resolve) => {
        Unirest.post('https://api.namechk.com/services/check.json')
          .headers({
            'AUTHORIZATION': 'Bearer ',
            'Accept': 'application/vnd.api.v1+json',
          }).send({
            'site': sitename,
            username: name,
          }).end(function(response) {
            if (response.body.available == false){
              counter++;
            } else {
              userNamesAvailable.push(response.body);
            }
            resolve();
          });
      });  
    });

    Promise.all(requests).then(() => { 
      console.log(userNamesAvailable);
      callback(counter, dotcom);
    });
  }

  function finalCheck() {
    console.log('Start finalCheck')
    console.log(counter)
    console.log(dotcom)
    //Final Check for is a name is a go or not
    //If one social site is not available and the
    if (counter == 1 & dotcom == 'true') {
      console.log(5 - counter + ' social sites available')
      res.send("yes");
    } else {
      res.send("no")
    }
  }

请记住,异步函数javascript是一个特性,而不是你应该与之抗争的东西(我认为你正在尝试将你的 main 函数声明为async function)。首先尝试了解它们,您会发现它们是一个很大的优势。

那里有很多关于它们的文档... async Fucntion 理解 Promises

编辑:不要将您称为全局的变量作为参数发送,它们已经在被调用函数中可用。


推荐阅读