【问题标题】:JS Promise: control flowJS Promise:控制流
【发布时间】:2017-03-09 14:20:21
【问题描述】:

我必须通过 API 设置一些东西。重要的是,不同的功能是在彼此之后执行的。所有列出的函数都返回一个正确的承诺。

a(analyticsConfig._listConfig)
    .then(function() {
        return b(listName, analyticsConfig._fieldConfig);
    })
    .then(function() {
        return c(listName)
    })
    .then(function() {
        return d(analyticsConfig._roleConfig);
    })

我想使用 a.then(b(listName, analyticsConfig._fieldConfig)) 之类的东西,但你可能知道这行不通。

还有其他方法吗?

【问题讨论】:

    标签: javascript promise chaining


    【解决方案1】:

    这只有在b 返回一个返回承诺的函数时才有效。您总是必须函数作为回调传递给then,这是没有办法的。然而,有很多方法可以构建一个。

    抛开部分应用程序(使用bind 或其他)、currying 和诸如此类的东西,您最好的选择是 ES8 async/await

    (async function() {
        await a(analyticsConfig._listConfig);
        await b(listName, analyticsConfig._fieldConfig);
        await c(listName);
        await d(analyticsConfig._roleConfig);
    })();
    

    或 ES6 箭头函数:

    a(analyticsConfig._listConfig)
    .then(() => b(listName, analyticsConfig._fieldConfig))
    .then(() => c(listName))
    .then(() => d(analyticsConfig._roleConfig))
    

    【讨论】:

    • 可能有效,尽管我使用了其他解决方案,因为我不允许使用 ES5+ 功能。 (但仍然赞成!)
    【解决方案2】:

    你可以写成

    a.then(b.bind(null, listName, analyticsConfig._fieldConfig))
    

    或者,如果您使用 babel 转译您的代码,或者您的目标是 node > v4.,您可以这样做

    a.then(() => b(listName, analyticsConfig._fieldConfig))
    

    【讨论】:

    • 请注意,任何 IE 浏览器都不支持箭头功能。
    • 我会 bindnull,而不是 this,以更紧密地模拟原始呼叫
    • 很好的答案,非常感谢。错误处理呢?有没有办法为整个链条使用一个.catch()
    【解决方案3】:

    你可以绑定它:

    a.then(b.bind(context,listName,analyticsConfig._fieldConfig))
    

    请务必将预期的上下文绑定到它。

    the docs

    bind() 方法创建一个新函数,在调用该函数时,将其 this 关键字设置为提供的值,并在调用新函数时将给定的参数序列置于任何提供的参数之前。

    【讨论】:

      【解决方案4】:

      您可以使用 async/await 执行以下操作:

      function a() {
          console.log('Getting A...');
          return new Promise((resolve, reject) => {
              setTimeout(() => {
                  resolve('Hello A!');
              }, 1000);
          });
      }
      
      function b() {
          console.log('Getting B...');
          return new Promise((resolve, reject) => {
              setTimeout(() => {
                  resolve('Hello B!');
              }, 1000);
          });
      }
      
      function c() {
          console.log('Getting C...');
          return new Promise((resolve, reject) => {
              setTimeout(() => {
                  resolve('Hello C!');
              }, 1000);
          });
      }
      
      function d() {
          console.log('Getting D...');
          return new Promise((resolve, reject) => {
              setTimeout(() => {
                  resolve('Hello D!');
              }, 1000);
          });
      }
      
      async function getAll() {
          await a();
          await b();
          await c();
          await d();
          console.log('Done');
      }
      

      【讨论】:

        猜你喜欢
        • 2017-04-30
        • 2016-03-20
        • 2016-05-31
        • 2015-05-04
        • 1970-01-01
        • 1970-01-01
        • 2023-03-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多