有条件地调用一个承诺(或不调用),但将结果返回另一个承诺

时间:2019-02-05 04:40:17

标签: javascript node.js asynchronous promise

尝试以不涉及嵌套承诺的方式编写以下代码时遇到麻烦。

function trickyFunction(queryOptions, data) {
  return new Promise((resolve, reject) => {
    if (data) {
      resolve(data);
    } else {
      // ... a bunch of conditions to check and/or modify queryOptions. These checks and mods
      // are vital but only required if data is not passed in. ...
      if (anErrorHappensHere) {
        reject('Oh no, an error happened');
      }

      somePromise(queryOptions).then((result) => {
        resolve(result);
      });
    }
  }).then((result) => {
    criticalOperation1(result);
    // the code here is long and shouldn't be duplicated
  });
}

我真的不喜欢somePromise之后的.then()链,因为它位于new Promise内,但是我真的没有办法解决。如果我不遵守条件,那么我将不得不复制criticalOperation1代码,这里不是一个选择。 else块中的条件检查仅应在未传递data的情况下进行。在我的情况下,不允许执行其他功能,在我的情况下,也不允许使用async / await。

有人有什么想法吗?我已经与Promises合作了一段时间,但是这个让我很沮丧。

2 个答案:

答案 0 :(得分:1)

在这种情况下,我只会避免使用new Promise语法,而应尽早启动诺言链。

function trickyFunction(queryOptions, data) {
  return Promise.resolve()
    .then( () => {
      if (data) {
        return Promise.resolve(data);
      } else {
        // ... a bunch of conditions to check and/or modify queryOptions. These checks and mods
        // are vital but only required if data is not passed in. ...
        if (anErrorHappensHere) {
          // Could also just throw here
          return Promise.reject('Oh no, an error happened');
        }

        return somePromise(queryOptions);
      }
    })
   .then((result) => {
      criticalOperation1(result);
      // the code here is long and shouldn't be duplicated
    });
}

答案 1 :(得分:1)

function trickyFunction(queryOptions, data) {
    return new Promise((resolve, reject) => {
    if (anErrorHappensHere) {
        reject('Oh no, an error happened');
    }
    resolve({data, queryOptions});
    }).then((obj) => {
        if(obj.data){
        return Promise.resolve(obj.data);
        } else {
        return somePromise(obj.queryOptions)
       }
    }).then((result) => criticalOperation1(result));
    .catch((err)=> console.log(err));
}