【问题标题】:Implement javascript promise or async/await [duplicate]实现 javascript promise 或 async/await [重复]
【发布时间】:2021-11-05 13:41:00
【问题描述】:

我在编程方面比较新; Promise 和 async/await 功能的概念是我很难理解的。但我知道在这种情况下我应该使用它。

背景:使用 Node、Express、XML2js npm 包来解析我正在使用的 XML 数据、XMLhttpRequest 和用于模板的 EJS 构建一个原型银行应用程序。 我的 server.js 中有这条获取路线:


    const parseString = require('xml2js').parseString;
    
    app.get('/home', (req, res) => {
     makeCall(`<root>
      <slipped>
        <mail>
          <alike>-1845676614.3625278</alike>
          <paid>uncle</paid>
          <kill>something</kill>
          <name>Stephen<name>
          <men>such</men>
          <firm>rubbed</firm>
          <using>yesterday</using>
        </mail>
      </slipped>
      <pour>-1247721160</pour>
      <poet>language</poet>
      <sets>-1907281866</sets>
      <treated>proper</treated>
      <judge>781679047</judge>
     </root>`)
    //Putting the format of the XML *response* above, to show what I am rendering from
      setTimeout(function () {
        res.render('home.ejs', {
          name: dataList[0].root.slipped.mail.name
        })
      }, 1000);
    }) 

我想让应用等待并完成 makeCall(), home.ejs 被渲染之前。如果我不等待,那么它将传播旧值。它确实像现在这样工作,但我相信有一种更有效的方法来做到这一点。

如何使用 Promise 或 async/await 行为而不是 setTimeout 重写上述逻辑?

作为参考,makeCall():


    const makeCall = (call) => {
      myRequest.open('POST', 'http://111.222.3.444:55555')
      myRequest.setRequestHeader('Content-Type', "application/x-www-form-urlencoded");
      myRequest.send(call)
      myRequest.onload = () => {
        if (myRequest.status === 200) {
          parseString(myRequest.responseText, (err, result) => {
            dataList.unshift(result)
          })
        } else {
          console.log('Something went wrong, status code: ' + myRequest.status)
        }
      }
    } 

提前感谢您为我提供的任何帮助:)

【问题讨论】:

    标签: javascript node.js xmlhttprequest ejs xml2js


    【解决方案1】:

    在 makeCall 中返回一个 Promise,这样你就可以在你的 main 方法中等待它。这是一个例子

    const makeCall = (call) => {
      return new Promise((resolve, reject) => {
        myRequest.open('POST', 'http://111.222.3.444:55555')
        myRequest.setRequestHeader('Content-Type', "application/x-www-form-urlencoded");
        myRequest.send(call)
        myRequest.onload = () => {
          if (myRequest.status === 200) {
            parseString(myRequest.responseText, (err, result) => {
              dataList.unshift(result);
              resolve();
            })
          } else {
            console.log('Something went wrong, status code: ' + myRequest.status)
            reject();
          }
        }
      });
    } 
    

    然后您可以等待它完成以继续您的 main 方法。您可以通过使用以下承诺来做到这一点:

    makeCal(...)
    .then(() => your_success_logic)
    .catch((e) => your_error_logic);
    

    或者你可以像这样使用 async/await:

    app.get('/home', async (req, res) => {
        await makeCal(...);
        res.render('home.ejs', {
          name: dataList[0].root.slipped.mail.name
        });
    });
    

    【讨论】:

      【解决方案2】:

      您可以使用new Promise 构造函数进行异步操作。它需要一个带有两个回调(resolve,reject)的函数。如果失败,拒绝它。如果成功,您可以使用resolve。节点 10 及以上您可以像这样使用async 函数并使用await 关键字等待异步函数解析或拒绝,然后再继续。

      const parseString = require('xml2js').parseString;
          
         app.get('/home', async (req, res) => {
          await makeCall(`<root>
           <slipped>
             <mail>
               <alike>-1845676614.3625278</alike>
               <paid>uncle</paid>
               <kill>something</kill>
               <name>Stephen<name>
               <men>such</men>
               <firm>rubbed</firm>
               <using>yesterday</using>
             </mail>
           </slipped>
           <pour>-1247721160</pour>
           <poet>language</poet>
           <sets>-1907281866</sets>
           <treated>proper</treated>
           <judge>781679047</judge>
          </root>`)
      
         //Putting the format of the XML *response* above, to show what I am rendering from
          res.render('home.ejs', {
            name: dataList[0].root.slipped.mail.name
          })
         }) 
      
      const makeCall = (call) => {
        return new Promise((resolve, reject) => {
          myRequest.open('POST', 'http://111.222.3.444:55555')
          myRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
          myRequest.send(call)
          myRequest.onload = () => {
            if (myRequest.status === 200) {
              parseString(myRequest.responseText, (err, result) => {
                if (err) {
                  reject(err)
                } else {
                  dataList.unshift(result)
                  resolve()
                }
              })
            } else {
              console.log('Something went wrong, status code: ' + myRequest.status)
              reject(new Error(''Something went wrong, status code: ' + myRequest.status'))
            }
          }
        })
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-11
        • 2018-03-24
        • 2021-05-13
        • 2023-04-08
        • 2023-03-10
        • 1970-01-01
        • 2020-06-06
        • 2019-05-24
        相关资源
        最近更新 更多