bluebird有一个说服函数来把函数包装在承诺中吗?

Does bluebird have a convince function for wrapping functions in promises?

本文关键字:函数 承诺 包装 有一个 bluebird      更新时间:2023-09-26

我有一个函数对象。这些函数并不总是完全承诺的。

例如:

function helloWorld(string){
  if(string == "foo") throw new Error("string is foo")
  return aPromise(string)
}

如果string是"foo",那么这将抛出一个错误,该错误不会被catch调用捕获。

我宁愿写像上面这样干净的代码,而不是这样:

function helloWorld(string){
  return Promise.resolve(){
    if(string == "foo") throw new Error("string is foo")
    return aPromise(string)
  }
}

所以我创建了这些映射到对象上的函数,并添加了嵌套的Promise.resolve

makePromises: function(obj){
  return _.mapObject(obj, function(fn){
    return function(){
      var args = _.values(arguments)
      return Promise.resolve().then(function(){
        return fn.apply(null, args)
      })
    }
  })
},
makeNestedPromises:function(obj){
  return _.mapObject(obj, function(fn){
    return function(){
      var args = _.values(arguments)
      var value = fn.apply(null, args)
      return function(){
        var args = _.values(arguments)
        return Promise.resolve().then(function(){
          return value.apply(null, args)
        })
      }
    }
  })
}

我想知道这是否已经存在于蓝鸟像promisifyAll,但似乎同步函数(没有回调),或者如果其他人发现这很有用。

所以promise似乎是这样做的,只是不像我想的那样使用嵌套函数。

var Promise = require("bluebird")
var concat = function(one, two){
  return Promise.resolve(one + " " + two)
}
var fns = {}
fns.hello = function(name, rank){
  if(name == "tom") throw new Error("tom unauthorized")
  return concat(name, rank)
}
Promise.promisifyAll(fns)
fns.helloAsync("tom", "developer")
  .catch(function(e){
    console.log(e)
  })

var Promise = require("bluebird")
var concat = function(one, two){
  return Promise.resolve(one + " " + two)
}
var fns = {}
fns.hello = function(unauthorized){
  return function(name, rank){
    if(name == unauthorized) throw new Error("unauthorized")
    return concat(name, rank)
  }
}
Promise.promisifyAll(fns)
// here promisify thinks that the top level function should be a promise
fns.helloAsync("tom")("tom", "developer")
  .catch(function(e){
    console.log(e)
  })

是的,您可以使用Promise.method:

var helloWorld = Promise.method(function helloWorld(string) {
  if(string == "foo") throw new Error("string is foo")
  return aPromise(string)
});

你应该只对异步回调函数使用承诺,它不适用于同步或返回承诺的函数(尽管它可以捕获同步异常)。

我创建了一个Promise.methodAll和一个deep可选参数。使用@Bergi的答案中的Promise.method

var Promise = require("bluebird")
var _ = require("underscore")
Promise.methodAll = function(obj, deep){
  return _.mapObject(obj, function(fn){
    if(!deep) return Promise.method(fn)
    return function(){
      var nestedFn = fn.apply(null, _.values(arguments))
      return Promise.method(nestedFn)
    }
  })
}
var concat = function(one, two){
  return Promise.resolve(one + " " + two)
}
var deep = {}
deep.authorize = function(unauthorized){
  return function(name, rank){
    if(name == unauthorized) throw new Error("unauthorized")
    return concat(name, rank)
  }
}
deep = Promise.methodAll(deep, true)
var normal = {}
normal.authorize = function(name, rank){
  if(name == "tom") throw new Error("tom unauthorized")
  return concat(name, rank)
}
normal = Promise.methodAll(normal)
normal.authorize("tom", "developer")
  .catch(function(e){
    console.log(e) //[Error: tom unauthorized]
  })
deep.authorize("tom")("tom", "developer")
  .catch(function(e){
    console.log(e) //[Error: unauthorized]
  })