【问题标题】:async.applyEachSeries converted to highland.jsasync.applyEachSeries 转换为 highland.js
【发布时间】:2014-11-22 08:14:36
【问题描述】:

我使用async.applyEachSeries 让这个 sn-p 工作正常。

var async = require("async");

function firstThing(state, next) {
  state.firstThingDone = true;
  setImmediate(next);
}

function secondThing(state, next) {
  state.secondThingDone = true;
  setImmediate(next);
}

var state = {};
async.applyEachSeries([
  firstThing,
  secondThing
], state, function (error) {
  console.log(error, state);
});

我已经多次尝试将其转换为 highland.js,但我并没有摸索那里的管道。我很确定我需要为 firstThing 和 secondThing 做 _.wrapCallback(firstThing) 但不确定我是否需要 _.pipeline.series() 或什么。

【问题讨论】:

    标签: async.js highland.js


    【解决方案1】:

    目前还没有很好的 1:1 翻译,因为 Highland 缺少 'applyEach',但是通过更改(或包装) firstThing 和 lastThing 函数,您可能会得到足够好的结果:

    var _ = require('highland');
    
    /**
     * These functions now return the state object,
     * and are wrapped with _.wrapCallback
     */
    
    var firstThing = _.wrapCallback(function (state, next) {
      state.firstThingDone = true;
      setImmediate(function () {
        next(null, state);
      });
    });
    
    var secondThing = _.wrapCallback(function (state, next) {
      state.secondThingDone = true;
      setImmediate(function () {
        next(null, state);
      });
    });
    
    var state = {};
    
    _([state])
      .flatMap(firstThing)
      .flatMap(secondThing)
      .apply(function (state) {
        // updated state
      });
    

    【讨论】:

      【解决方案2】:

      在我自己为 Highland 放弃异步的尝试中,我开始经常使用 .map(_.wrapCallback).invoke('call')。我们可以在这里使用它:

      var _ = require('highland');
      
      var state = {};
      
      function firstThing(state, next) {
        state.firstThingDone = true;
        setImmediate(next);
      }
      
      function secondThing(state, next) {
        state.secondThingDone = true;
        setImmediate(next);
      }
      
      _([firstThing, secondThing])
        .map(_.wrapCallback)
        .invoke('call', [null, state])
        .series().toArray(function() {
          console.log(state)
        });
      

      这让我们可以保持你的函数原样,它很好地扩展到两个以上的“事物”,我认为它更像是对 applyEachSeries 的直接分解。

      如果我们需要绑定this或者为每个函数传递不同的参数,我们可以在构造流的时候使用.bind并省略call参数:

      _([firstThing.bind(firstThing, state),
        secondThing.bind(secondThing, state)])
        .map(_.wrapCallback)
        .invoke('call')
        .series().toArray(function() {
          console.log(state)
        });
      

      另一方面,这种方法的副作用更大;我们流中的东西不再是我们最终要转换和利用的东西。

      最后,不得不在结尾使用.toArray 感觉很奇怪,尽管这可能只是将.done(cb) 添加到Highland 的一个论据。

      【讨论】:

        猜你喜欢
        • 2023-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多