【问题标题】:Struggling with javascript Promise与 javascript Promise 斗争
【发布时间】:2020-11-22 12:13:57
【问题描述】:

我正在努力让 javascript Promises 正常工作。
我正在寻找关于我做错了什么的一两个指针。下面是我的代码。我正在尝试将loadUserPayRateWrapped() 转换为从数据库获取数据的函数。 我得到的行为是,在$.getJSON() 有机会获取它的数据之前,整套包装器代码仍在返回。

等待数据请求的函数:

function loadUserPayRateWrapped( projectId )
{

    var URI = "/projects/getAssignedResponsibilities?projectId=" + projectId;
    $.getJSON( URI, function ( data )
    {
        if ( data === null )
            return getDataFromCookie( "payRate" );
        else
        {
            const employeeId = getDataFromCookie( "empId" );
                    if ( data[ 0 ].alternatePay === null )
                return getDataFromCookie( "payRate" );
                    var altPayArray = JSON.parse( data[ 0 ].alternatePay );
                    $.each( altPayArray, function ( idx, element )
            {
                if ( element.uid == employeeId )
                    return element.pay;
            } );
        }

        // nothing was found, so return the regular pay rate
        return getDataFromCookie( "payRate" );

    });

}

包装承诺函数:

function loadUserPayRatePromise( projectId )
{
    var payRateProm = new Promise((resolve, reject) =>
    {
        var payRate = loadUserPayRateWrapped( projectId );
        resolve( payRate );
    });

    payRateProm.then( result => { return payRate } );
}

异步调用者:

async function loadUserPayRate( projectId )
{
    try
    {
        const pay = await loadUserPayRatePromise( projectId );
        return pay;
    }
    catch(error)
    {

    }
}

需要数据的主线代码:

// add the default pay rate for this user
var payRate = loadUserPayRate( data.projectId );
$( "#hourlyRate" ).val( payRate.toFixed(2) );    //payRate must be populated before this line

【问题讨论】:

    标签: javascript promise es6-promise


    【解决方案1】:

    只需将 $.getJSON 从回调样式“转换”为 Promise 就足够了。

    这是我的例子,也许你自己处理错误情况。

    function loadUserPayRateWrapped(projectId) {
      return new Promise((resolve, reject) => { // wrap callback function into a promise
        var URI = "/projects/getAssignedResponsibilities?projectId=" + projectId;
        $.getJSON(URI, function (data) {
          const defaultPayRate = getDataFromCookie("payRate"); // extract to variable to reuse
          if (data === null) { // recommend style: if block with {}
            return resolve(defaultPayRate);
          } else {
            const employeeId = getDataFromCookie("empId");
            if (data[0].alternatePay === null) {
              return resolve(defaultPayRate);
            }
            var altPayArray = JSON.parse(data[0].alternatePay);
            var foundAltPay = altPayArray.find(p => p.uid === employeeId); // why $.each ??
            // nothing was found, so return the regular pay rate
            return resolve(foundAltPay || defaultPayRate)
          }
        });
      });
    }
    

    现在,loadUserPayRateWrapped 返回一个 Promise。然后可以使用 Promise 风格调用函数,或者使用async/await 风格:

    // Promise style
    loadUserPayRateWrapped(data.projectId)
      .then(payRate => {
        $("#hourlyRate").val(payRate.toFixed(2));
      });
    
    // async/await style with IIFE
    (async () => {
      const payRate = await loadUserPayRateWrapped(data.projectId); // wait
      $("#hourlyRate").val(payRate.toFixed(2));
    })();
    

    【讨论】:

      【解决方案2】:

      我没有使用$.fetchJSON,您绝对可以使用,而是使用window.fetch 来执行此操作。并添加了asyncawait,这样我们就不会使用then 块了。

      // Added async
      async function loadUserPayRateWrapped( projectId )
      {
      
          var URI = "/projects/getAssignedResponsibilities?projectId=" + projectId;
          
          // Modified this line
          const data = await window.fetch(URI);
      
          if ( data === null )
              return getDataFromCookie( "payRate" );
          else
          {
              const employeeId = getDataFromCookie( "empId" );
              if ( data[ 0 ].alternatePay === null )
                  return getDataFromCookie( "payRate" );
              var altPayArray = JSON.parse( data[ 0 ].alternatePay );
              $.each( altPayArray, function ( idx, element )
              {
                  if ( element.uid == employeeId )
                      return element.pay;
              } );
          }
      
          return getDataFromCookie( "payRate" );
      
      }
      
      // Added async
      async function loadUserPayRatePromise( projectId )
      {
          var payRateProm = new Promise((resolve, reject) =>
          {
              // Added await
              var payRate = await loadUserPayRateWrapped( projectId );
              resolve( payRate );
          });
      
          payRateProm.then( result => { return payRate } );
      }
      
      async function loadUserPayRate( projectId )
      {
          try
          {
              const pay = await loadUserPayRatePromise( projectId );
              return pay;
          }
          catch(error)
          {
      
          }
      }
      
      

      另外,在下面的块中

      $.each( altPayArray, function ( idx, element ) {
          if ( element.uid == employeeId )
              return element.pay;
      });
      

      从函数内部返回element.pay 将导致它返回值给内部函数而不是外部函数。因此,您可以这样做

      for (const element of altPayArray) {
          if ( element.uid == employeeId ) {
              return element.pay;
          }
      }
      

      【讨论】:

        【解决方案3】:

        您需要在loadUserPayRatePromise返回承诺

        function loadUserPayRatePromise( projectId )
        {
            var payRateProm = new Promise((resolve, reject) =>
            {
                var payRate = loadUserPayRateWrapped( projectId );
                resolve( payRate );
            });
        
            return payRateProm.then( result => { return payRate } );
        }
        

        【讨论】:

          【解决方案4】:

          你只想从你的函数中返回一个承诺,不要命名它。

          function loadUserPayRatePromise( projectId ) {
              return new Promise((resolve, reject) => {
                  var payRate = loadUserPayRateWrapped( projectId );
                  resolve( payRate );
              });    
          }
          

          让它们异步

          async function loadUserPayRatePromise( projectId ) {
              return new Promise(async (resolve, reject) => {
                  var payRate = loadUserPayRateWrapped( projectId );
                  resolve( payRate );
              });    
          }
          

          【讨论】:

            猜你喜欢
            • 2020-09-18
            • 2018-05-23
            • 2013-11-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-30
            • 2014-10-04
            相关资源
            最近更新 更多