【问题标题】:Finish recursive promise function execution in Javascript在 Javascript 中完成递归 promise 函数的执行
【发布时间】:2018-12-05 06:31:29
【问题描述】:

我有 3 个函数,func1() 将一些 api 数据返回给 func2() 并且 func2() 从 func3() 调用。Func2() 有一个 Promise 返回类型,在 Func2() 中我只解决某些条件是遇到其他情况我想调用相同的 Func2() 直到条件满足但是当我执行 func3() 时。我没有看到来自 func2() 的响应。我收到错误消息“回调”参数必须是 函数:TypeError:“回调”参数必须是函数。

//func1()
const apiRequest = (options, func_callback) => {
  request(options, (err, res, body) => {
    let result = {
      body: body,
      error: err,
      res: res
    }
    func_callback(result);
  });
};
//func2
const getPromise = (options) => {
  return new Promise((resolve, reject) => {
    apiRequest(options, (response) => {
      if (response.error) {
        reject(response.error);
      }
      if (response.body.hasOwnProperty('message')) {
        console.error(`Error: Invalid token`);
        new Promise((resolve, reject) => {
          const payload = {
            url: 'https://abc',
            form:{},
            method: 'post'
          };
          request(payload, (err, res, body) => {
            if (err) {
              reject(err);
            }
            else {
              resolve(body);
            }
          });
        }).then((result) => {

          options.headers.Authorization = 'Bearer '+result;
          getPromise(options); // seems Issue having this line to call again
        });
      }
      else {
        resolve(response.body);
      }
    });
  });
};

// func3()
function getSession() {
  const options={url:''someurl',     
  getPromise.then(result => {
    console.log('all ID'+result); // I can not see result here
  .catch(error => {
    console.log('Error ', error);
  });
}

【问题讨论】:

    标签: javascript node.js promise es6-promise


    【解决方案1】:

    应该在包装apiRequest 的函数中创建一个promise。那个(“promisify-ing”)包装器除了构建一个在回调内部解决的 Promise 之外什么都不做。

    //func1()
    const apiRequest = (options, func_callback) => {
        request(options, (err, res, body) => {
            let result = {
                body: body,
                error: err,
                res: res
            }
            func_callback(result);
        });
    };
    
    // wrap the apiReqeust function in a promise.  place no other logic in here...
    const apiRequestP = (options) => {
        return new Promise((resolve, reject) => {
            apiRequest = (options, response => {
                (response.error)? reject(response.error) : resolve(response);
            })
        });
    };
    

    现在有一个返回承诺的包装器没有其他函数应该调用回调样式函数

    看起来func2 的意图是返回一个发出请求并添加逻辑以检查和修复身份验证挑战的承诺。为此,首先创建一个返回承诺的函数来修复已知需要它的请求的身份验证:

    // return a promise to make a token request followed by an auth'd version
    // of the request described in the options param
    const remediateAuth = (options) => {
        console.error(`Error: Invalid token`);
        const authOptions = { url: 'https://abc', form:{}, method: 'post' };
        return apiRequestP(authOptions).then(response => {
            options.headers.Authorization = 'Bearer '+response;
            return apiRequestP(options);
        }).then(response => response.body);
    }
    

    这样,func2 变得非常简单。请注意没有其他明确创建的承诺。另请注意,此函数是确保经过身份验证的请求的层,因此应用程序的大部分其余部分都可以调用它,而不是上述较低级别的函数:

    // was called func2
    const authedRequest = (options) => {
        return apiRequestP(options).then(response => {
            return (response.body.hasOwnProperty('message'))? remediateAuth(options) : response.body;
        });
    }
    

    【讨论】:

    • ,谢谢它帮助了我
    【解决方案2】:

    在您创建new Promise(…).then(…)if 条件下,您永远不会解决外部承诺。

    您可以通过在正确的位置添加 resolve 来解决这个问题,但无论如何您都不应该在 Promise 中创建 Promise。你应该在尽可能低的水平上做出承诺。让api_request 返回一个承诺,而不是让它接受回调。

    // func1()
    function apiRequest(options, func_callback) {
      return new Promise((resolve, reject) => {
        request(options, (err, res, body) => {
          if (err) reject(err);
          else resolve({ body, res });
        });
      });
    }
    

    您甚至可以重复使用它,并使用适当的承诺链:

    //func2
    functon getPromise(options) {
      return apiRequest(options).then(response => {
        if (response.body.hasOwnProperty('message')) {
          console.error(`Error: Invalid token`);
          const payload = {
            url: 'https://abc',
            form:{},
            method: 'post'
          };
          return apiRequest(payload).then(result => {
            options.headers.Authorization = 'Bearer '+result.body;
            return getPromise(options); // seems Issue having this line to call again
          });
        } else {
          return response.body;
        }
      });
    }
    

    【讨论】:

      【解决方案3】:

      似乎在你的函数'getPromise'中你得到了(resolve,reject),但是在函数内部你创建了另一个promise,然后你创建了另外2个名为(resolve,reject)的变量,它覆盖了原来的resolve,然后你真的没有任何 getPromise 的返回值

      第一个任务:

      const getPromise = (options) => {
            return new Promise((resolve, reject) => {
      

      第二个作业:

      console.error(`Error: Invalid token`);
                  new Promise((resolve, reject) => {
      

      【讨论】:

        猜你喜欢
        • 2021-11-11
        • 2015-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多