承诺链接-副作用或直通变量

时间:2019-04-24 19:50:02

标签: javascript ecmascript-6

我只使用ES6,没有使用库,例如​​Bluebird或Async。我也不想使用async / await。

这是副作用代码:

function getManager(name) {
   return new Promise(resolve => {
       resolve({
          id: 123,
          location: 'San Diego'
       });
   });
}

function getEmployees(managerId) {
   return new Promise(resolve => {
       resolve([
          {
              id: 321,
              name: 'Jack'
              location: 'Detroit'
          },
          {
              id: 456,
              name: 'Jill'
              location: 'Cleveland'
          }
       ]);
   });
}

var manager;
getManager('Bob').then(function (result) {
  manager = result;
  return getEmployees(manager.id);
}).then(function (employees) {
  // okay, I have both the "manager" and the "employess"
});

这是传递变量:

function getManager(name) {
   return new Promise(resolve => {
       resolve({
          id: 123,
          location: 'San Diego'
       });
   });
}

function getEmployees(manager) {
   return new Promise(resolve => {
       resolve({
          employees: [
              {
                  id: 321,
                  name: 'Jack'
                  location: 'Detroit'
              },
              {
                  id: 456,
                  name: 'Jill'
                  location: 'Cleveland'
              }
          ],
          manager: manager
       });
   });
}

getManager('Bob').then(function (result) {
  manager = result;
  return getEmployees(manager);
}).then(function (results) {
  // okay, I have both the "results.manager" and the "results.employess"
});

还有其他方法来处理诺言链中的变量吗?使用副作用代码有不利之处吗?副作用似乎更为直接。

3 个答案:

答案 0 :(得分:1)

Pass-Thru更好

直通技术更好的原因是它可以执行以下操作:

  1. 它允许您多次使用这些函数,而不会覆盖全局变量并以错误的值结束。
  2. 您可以使用这些函数并传递这些承诺,而不管任何全局变量定义(甚至是局部变量定义)如何。
  3. 避免使用全局变量可以使您的代码更简洁,更易于推理。
  4. 使manager成为返回类型的一部分,从而赋予更好的智能感知能力。

答案 1 :(得分:1)

我建议使用混合解决方案:

  • 应避免第一个解决方案的副作用(更改全局变量)
  • 使函数getEmployees适应解决该函数本身不存在的问题似乎也不正确。

您可以使用Promise.all将先前的结果与当前的结果合并。这样,您就可以同时拥有两种选择中的最佳选择:

function getManager(name) {
    return Promise.resolve({
        id: 123,
        location: 'San Diego'
    });
}

function getEmployees(manager) {
    return Promise.resolve([{
        id: 321,
        name: 'Jack',
        location: 'Detroit'
    }, {
        id: 456,
        name: 'Jill',
        location: 'Cleveland'
    }]);
}

getManager('Bob').then(function (manager) {
    return Promise.all([manager, getEmployees(manager)]);
}).then(function ([manager, employees]) {
    console.log(manager.location, employees.map(({name})=>name).join());
});

答案 2 :(得分:0)

我知道您说过您不想使用async / await,但这就是您这样做的样子:

async function main() {
  const manager = await getManager('Bob');
  const employees = await getEmployees(manager);
  console.log(manager, employees);
}