解决嵌套的承诺

时间:2017-08-09 16:54:22

标签: javascript node.js promise

我想知道如何处理参数嵌套的promise。

我有这样的代码:

'use strict';

function fetchData(tableName) {
  new Promise((resolve, reject) => {
    if (tableName === 'tableName2') {
      setTimeout(reject, 200, tableName);
    } else {
      setTimeout(resolve, 200, tableName);
    }
  });
}

function notifyUser(data) {
  console.log(data); // get only undefined 3 times
  new Promise((resolve) => {
    setTimeout(resolve, 200, data);
  });
}

let cont = { fail: () => '', success: () => console.log };
function verifyAndNotify(context) {
  let actions = [];
  ['tableName1','tableName2','tableName3'].map(tableName => {
    actions.push(notifyUser(fetchData(tableName))); // how to deal with this???
  });

  Promise.all(actions)
    .then(success => {
      console.log(`All is ok ${success}`);
    }).catch(error => {
      console.log(`error with: ${error}`);
      errors.push(error);
    });

  if (errors.lenght > 0) {
    return context.fail(`Errors: ${errors}`);
  } else {
    return context.success(`Success`);
  }
}

verifyAndNotify(cont);

问题是我需要先解析参数,然后再将其提供给方法。我可能混合了一些我在JS上非常糟糕的事情。

我想通过每个tableName通知用户,如果有一个"表"我想提出错误。操作失败(获取数据或通知)。

编辑1:

评论和回答后的第一个工作版本:

'use strict';

function fetchData(tableName) {
  return new Promise((resolve, reject) => {
    if (tableName === 'tableName2') {
      setTimeout(reject, 200, tableName);
    } else {
      setTimeout(resolve, 200, tableName);
    }
  });
}

function notifyUser(data) {
  console.log(data);
  return new Promise((resolve) => {
    setTimeout(resolve, 200, data);
  });
}

const cont = { fail: (msg) => console.log('' + msg), done: (msg) => console.log('' + msg) };
function verifyAndNotify(context) {
  const errors = [];
  const actions = ['tableName1', 'tableName2', 'tableName3'].map(tableName =>
    fetchData(tableName).then(notifyUser).catch(error => {errors.push(error);}));

  Promise.all(actions)
    .then(success => {
      if (errors.length) throw errors;
      else {
        context.done(`Success ${success}`);
      }
    }).catch(errors => {
      context.fail(`Errors: ${errors}`);
    });
}

verifyAndNotify(cont);

1 个答案:

答案 0 :(得分:2)

正如@Grundy所说,第一个问题是你的函数需要返回promises(return new Promise ...)。

就行动清单而言,您可能希望将数组映射到承诺数组:

const actions = ['tableName1', 'tableName2', 'tableName3'].map(tableName =>
    fetchData(tableName).then(notifyUser));

此外,您似乎想要一个包含错误的每个承诺的列表,在这种情况下,您希望为每个操作承诺添加catch,因为Promise.all会尽快拒绝一个动作拒绝。例如:

const errors = [];
const actions = ['tableName1', 'tableName2', 'tableName3'].map(tableName =>
    fetchData(tableName).then(notifyUser).catch(errors.push));
Promise.all(actions)
    .then(success => {
        if (errors.length) throw errors;
        else {
            console.log(`All is ok ${success}`);
            context.done(`Success`);
        }
    }).catch(errors => {
        context.fail(`Errors: ${errors}`);
    });