返回promises

时间:2015-07-25 08:53:24

标签: javascript promise bluebird

这里我有4个函数返回promises。如果你运行hello并将每个传递给下一个.then,你会得到一个长字符串。

var hello = function(str){
  return Promise.resolve(str+ "hello")
}
var world = function(str){
  return Promise.resolve(str+ "world")
}
var foo = function(str){
  return Promise.resolve(str+ "foo")
}
var bar = function(str){
  return Promise.resolve(str+ "bar")
}

// hello("alpha").then(world).then(foo).then(bar).then(console.log)
// => alphahelloworldfoobar

我希望能够将函数的平面数组传递给函数,并返回一个将它们全部嵌套的函数。

var arr = wrapThen([
  hello,
  world,
  foo,
  bar
])

arr("alpha").then(console.log)

这可能吗?蓝鸟是否提供此服务?

这就是我一起攻击的地方:

function wrapThen(arr){
  var headPromise = arr.shift()
  return function(){
    var args = _.values(arguments)
    var init = headPromise(args)
    var values = []
    return Promise.each(arr, function(item){
      init = init.then(item)
      return init.then(function(value){
        values.push(value)
        return value
      })
    }).then(function(){
      return _.last(values)
    })
  }
}

3 个答案:

答案 0 :(得分:2)

当然,对于蓝鸟来说这很容易,reduce,这基本上是reduce所做的事情(总结果):

let result = Promise.reduce([hello, world, foo, bar], function(result, action){
    return action(result);
}, "alpha");

在ES2015表示法中,这变得更加冗长:

let {reduce} = Promise;
let result = reduce(arr, (result, action) => action(result), "alpha");

var hello = function(str){
  return Promise.resolve(str+ "hello");
};
var world = function(str){
  return Promise.resolve(str+ "world");
};
var foo = function(str){
  return Promise.resolve(str+ "foo");
};
var bar = function(str){
  return Promise.resolve(str+ "bar");
};


Promise.reduce([hello, world, foo, bar], function(result, action){
    return action(result);
}, "alpha").then(function(endResult){ 
    console.log(endResult);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.33/bluebird.min.js"></script>

答案 1 :(得分:0)

不确定您是否希望所有函数都获得相同的参数alpha或仍然作为序列传递,因此我同时编写两者,只需使用.reduce.map即可实现这两种方式。

var hello = function(str){
  return Promise.resolve(str+ "hello");
};
var world = function(str){
  return Promise.resolve(str+ "world");
};
var foo = function(str){
  return Promise.resolve(str+ "foo");
};
var bar = function(str){
  return Promise.resolve(str+ "bar");
};
 
// Wrap all functions in list, all give them the same value.
var wrapToArray = function(list) {
  
  return function(result) {
    var allP = list.map(function(item) {
      return item(result);
    });
    return Promise.all(allP);
  };
  
};

// Wraps all, and resolve them by array's sequence.
var wrapToSequence = function(list) {
  
   return  function(result) {
    // Create a promise that resolved with result first.
    var promise = Promise.resolve(result);
    // Use reduce to chain the functions.
    promise = list.reduce(function(prev, item) {
      return prev.then(item);
    }, promise);
    return promise;
  };

};

var arr = wrapToArray([hello, world, foo, bar]);
var arr2 = wrapToSequence([hello, world, foo, bar]);

arr("alpha").then(console.log.bind(console));
arr2("alpha").then(console.log.bind(console));
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.33/bluebird.min.js"></script>

Bluebird还提供.reduce.map以便更轻松地创建,以避免答案变得更长,演示在jsfiddle上。

var wrapToSequence = function(list) {
   return  function(result) {
    return  Promise.reduce(list, function(result, fn) {
      return fn(result);
    }, result);
  };
};

var wrapToArray = function(list) {
  return function(result) {
    return Promise.map(list, function(fn) {
      return fn(result);
    });
  };
};

答案 2 :(得分:0)

以下是使用Ramda如何执行此操作的示例。

var R = require("ramda")

var hello = function(str){
  return Promise.resolve(str+ "hello")
}
var world = function(str){
  return Promise.resolve(str+ "world")
}
var foo = function(str){
  return Promise.resolve(str+ "foo")
}
var bar = function(str){
  return Promise.resolve(str+ "bar")
}

var result = R.pipeP(hello, world, foo, bar)

result("alpha").then(console.log) // logs -> "alphahelloworldfoobar"

result("alpha") // promise -> "alphahelloworldfoobar"