使用Promises / Async-Await(Node.JS)修复代码

时间:2018-11-21 16:25:47

标签: javascript node.js

因此,我目前正在工作的一个项目上开发某些功能。该项目主要使用JavaScript-后端使用Node.JS,前端使用React.JS,我不得不承认我对这两个都不熟悉。我相信,如果我使用Promise或async / await功能,我编写的代码看起来会更好,并且工作效率更高(在这里问这个问题之前,我读了几篇关于它们的文章,但我仍然不确定如何在其中使用它们该项目的实际意义,因此我决定在此处询问社区)。我也浏览了这篇文章,但是我不确定我的实现是否确实执行了任何操作StackOverflow。 在这篇文章的结尾,我将在前端和后端粘贴一些代码,希望有人能够指出正确的方向。为了使事情更清楚-我不是在要求任何人为我重写代码,而是在解释原因是我做错了(或根本没有做)。

用例:

用户在网站的搜索栏中输入公司名称。然后,通过http-request将键入的字符串发送到后端,并检查数据库中的条目(以获取公司的徽标)-在这里,我正在运行一种算法来检查拼写错误并提出与键入的名称相似的名称,结果在将结果发送回数据库之前,可能要查询数据库两次以上,但是它始终可以正常工作。 前端接收到响应后,应该会发生一些事情-首先,应将另一个请求发送到Web以接收其他结果。如果收到正确的结果,那应该是该函数的结尾,否则它将再次向Google发送另一个请求,以从那里获取结果。

后端代码:

.post('/logo', (req, res) => {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

        if (req.body.key !== "" && req.body.key.trim().length > 0) {
            let results = {};
            let proposedNames = [];

            var promise1 = new Promise((resolve, reject) => {
                let getLogo = "SELECT title, img_dir FROM logo_approved WHERE LOWER(title) LIKE LOWER($1)";
                let searchedCompanyName = ["%"+req.body.key+"%"];

                db.queryDB(getLogo, searchedCompanyName, (data) => {
                    if (data.rows.length > 0){
                        results.databaseResults = data.rows;
                    }
                    resolve(data.rows);
                });
            });

            // Returns the list of all companies' names from the database
            var promise2 = new Promise((resolve, reject) => {
                let returnAllNames = "SELECT title, img_dir as img FROM logo_approved";
                db.queryDB(returnAllNames, [], (data) =>{
                    // Compare searched company's name with all names from the database
                    data.rows.forEach(function(element) {
                        // If name from the database is similar to the one searched for
                        // It's saved in propsedNames array and will be used later on for database query
                        if (jw.distance(req.body.key, element.title) > 0.7){
                            element.probability = parseFloat(jw.distance(req.body.key, element.title).toFixed(2));
                            proposedNames.push(element);
                        }
                    })
                    resolve(proposedNames);
                });
                    proposedNames.sort(function(a,b){return a.distance-b.distance});
                    results.proposedNames = proposedNames;
            });

            var promiseAll = Promise.all([promise1, promise2]);
            promiseAll.then(() => {
                res.send(results);
            });
    }   
        else {
            res.status(400);
            res.send("Can't search for an empty name");
        }
    })

前端代码:

  engraveLogoInputHandler() {
    let results = {};
    let loadedFromWeb = false, loadedFromClearbit = false, loadedFromDatabase = false;

    this.setState({
      engraveLogo: this.engravingLogo.value.length
    });
    // charsElthis.engravingInput.value
    if (inputLogoTimer) {
      clearTimeout(inputLogoTimer);
      // inputLogoTimer = null;
    }

    if (this.engravingLogo.value !== ''){
    // Wait to see if there is any new input coming soon, only render once finished to prevent lag
    inputLogoTimer = setTimeout(() => {

    request.post({url: NODEENDPOINT+'/logo', form: {key: this.engravingLogo.value}}, (err, res, body) => {
      if (err){
        console.log(err);
      }
      else {
        if (res.body && res.statusCode !== 400){
          results.database = JSON.parse(res.body);
          loadedFromDatabase = true;
        }
    }
  });

    request(link+(this.engravingLogo.value), (err, res, body) => {
      if (err) {
        console.log(err);
      }
      else {
        let jsonBody = JSON.parse(body);
        if (jsonBody && !jsonBody.error){
          let sources = [];
          let data = JSON.parse(body);
          for (let item of data) {
            sources.push({
              domain: item.domain,
              image: item.logo+'?size=512&grayscale=true',
              title: item.name
            });
          }
          loadedFromClearbit = true;
          results.clearbit = sources;
        }
      }
    });

    if (!loadedFromClearbit && !loadedFromDatabase){
    request('https://www.googleapis.com/customsearch/v1?prettyPrint=false&fields=items(title,displayLink)&key='+GOOGLE_CSE_API_KEY+'&cx='+GOOGLE_CSE_ID+'&q='+encodeURIComponent(this.engravingLogo.value), { json: true }, (err, res, body) => {
      if (err) {
        console.error(err);
      }
      else {
        if (body && body.items) {
          let sources = [];
          for (let s of body.items) {
            sources.push({
              domain: s.displayLink,
              image: 'https://logo.clearbit.com/'+s.displayLink+'?size=512&greyscale=true',
              title: s.title
            });
          }
          loadedFromWeb = true;
          results.googleSearches = sources;
        } else {
          console.error(body);
        }
      }
    });
  }

    console.log("Results: ", results);

    if (loadedFromClearbit || loadedFromWeb){
      console.log("Propose the logo to be saved in a local database");
    }
    }, 500);}
  }

因此,关于后端代码,我对promises的实现实际上在那里正确吗,并且有用吗?我可以在前端使用类似的内容并将前两个请求放入Promise,并且仅在前两个请求失败时才运行第三个请求吗? (失败意味着它们返回空结果)。 我以为我可以使用这样的逻辑(见下文)来捕捉诺言是否失败,但是那没有用,并且我收到一个错误消息,说我没有抓住拒绝:

var promise1 = new Promise((resolve, reject) => {
  // ... some logic there

  else {
    reject();
  }
});

var promise2 = promise1.catch(() => {
  new Promise((resolve, reject) => {
    // some logic for 2nd promise
  });
});

任何答案都值得赞赏。如前所述,我对JavaScript不太熟悉,这是我正在从事的第一个异步项目,因此我想确保我利用并适应了正确的行为和方法。 谢谢

0 个答案:

没有答案