首页 > 解决方案 > 在 Javascript 中完成递归 promise 函数的执行

问题描述

我有 3 个函数,func1() 将一些 api 数据返回给 func2() 并从 func3() 调用 func2()。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);
  });
}

标签: javascriptnode.jspromisees6-promise

解决方案


唯一应该创建 Promise 的地方是包装apiRequest. 那个(“promisify-ing”)包装器除了构建一个在回调内部解决的承诺之外什么都不做。

//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);
        })
    });
};

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

看起来的意图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;
    });
}

推荐阅读