写下承诺而不打开然后打电话

Tho*_*ggi 5 javascript function promise lodash bluebird

为了努力停止编写大量重复的代码,我试图不打开然后调用.我最好只喜欢从顶层传递函数.像这样.

function ensureLink(srcPath, dstPath){
  dstPath = fsRedux.predictDir(srcPath, dstPath)
  var dstDir = path.dirname(dstPath)
  return fsRedux.exists(dstPath)
    .then(_.partialRight(fsRedux.ifFalseThrow, false, new Error(dstPath+" exists cannot ensure link")))
    .then(_.bind(fsExtra.mkdirsAsync, fsExtra, dstDir))
    .then(_.bind(_.bind(fsExtra.linkAsync, fsExtra, srcPath, dstPath)))
}
Run Code Online (Sandbox Code Playgroud)

但是上面的代码不起作用.下面的测试表明您无法通过bound promisifyAll异步功能.原因是then值被传递到这些promises中,导致它们作为调用中的下一个参数,因为这些函数意味着它们作为回调触发,这就是为什么第一个测试错误出现Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.在mocha中.

var chai = require("chai")
var chaiAsPromised = require("chai-as-promised")
chai.use(chaiAsPromised)
chai.should()

var path = require("path")
var _ = require("lodash")
var mock = require("mock-fs")

var Promise = require("bluebird")
var fsRedux = require("./fs-redux")
var fsExtra = Promise.promisifyAll(require("fs-extra"))
var fs = Promise.promisifyAll(require("fs"))

mock({
  'path/hello-alpha.txt': 'file content here',
  'path/hello-beta.txt': 'file content here'
})

var dstPath = "path/to/fake/dir/"

function closedThen(srcPath, dstPath){
  dstPath = fsRedux.predictDir(srcPath, dstPath)
  var dstDir = path.dirname(dstPath)
  return fsRedux.exists(dstPath)
    .then(_.partialRight(fsRedux.ifFalseThrow, false, new Error(dstPath+" exists cannot ensure link")))
    .then(_.bind(fsExtra.mkdirsAsync, fsExtra, dstDir))
    .then(_.bind(_.bind(fsExtra.linkAsync, fsExtra, srcPath, dstPath)))
}

function openThen(srcPath, dstPath){
  dstPath = fsRedux.predictDir(srcPath, dstPath)
  var dstDir = path.dirname(dstPath)
  return fsRedux.exists(dstPath)
    .then(_.partialRight(fsRedux.ifFalseThrow, false, new Error(dstPath+" exists cannot ensure link")))
    .then(function(){
      return _.bind(fsExtra.mkdirsAsync, fsExtra, dstDir)()
    })
    .then(function(){
      return _.bind(fsExtra.linkAsync, fsExtra, srcPath, dstPath)()
    })
}

describe("issue", function(){
  describe("closedThen()", function(){
    it("should return then and run promise", function(){
      return closedThen("path/hello-alpha.txt", dstPath).then(function(){
        return fsExtra.readFileAsync("path/to/fake/dir/hello-alpha.txt", "utf8").should.eventually.equal("file content here")
      })
    })
  })
  describe("openThen()", function(){
    it("should return then and run promise", function(){
      return openThen("path/hello-beta.txt", dstPath).then(function(){
        return fsExtra.readFileAsync("path/to/fake/dir/hello-beta.txt", "utf8").should.eventually.equal("file content here")
      })
    })
  })
})
Run Code Online (Sandbox Code Playgroud)

存在哪些函数,或者包装绑定函数的方式将允许以这种方式处理promise?

更新:

我在寻找功能包装套件库(lodash有一堆人),允许为一个简单的界面partialing从我的质询时结合或环绕功能传递给一个then或内运行Promise.reduce.这样链接承诺真的很容易.

理想情况下,我只是想知道如何使线路工作,这是一种包装它的方式,以便当它从那时传递结果时它会忽略它.或推荐替代方案.

.then(_.bind(fsExtra.mkdirsAsync, fsExtra, dstDir))
Run Code Online (Sandbox Code Playgroud)

Tho*_*ggi 0

这是一个使用的示例Ramda

var Promise = require("bluebird")
var R = require("ramda")
var path = require("path")
var fs = Promise.promisifyAll(require("fs"))
var fse = Promise.promisifyAll(require("fs-extra"))

function ifThrow(value, desiredValue, error){
  if(value == desiredValue) throw error
  return value
}

var fsEnsureLink = function(srcpath, dstpath){
  return R.pipeP.apply(null, [
    R.always(fs.lstatAsync(srcpath).then(R.T, R.F)),
    R.partialRight(ifThrow, false, new Error("source path does not exist")),
    R.always(fs.lstatAsync(dstpath).then(R.T, R.F)),
    R.partialRight(ifThrow, true, new Error("destination path exists")),
    R.always(fse.mkdirsAsync(path.dirname(dstpath))),
    R.always(fs.linkAsync(srcpath, dstpath)),
    R.T,
  ])()
}

fsEnsureLink("./package.json", "./test/package.json")
// promise -> true || Error thrown
Run Code Online (Sandbox Code Playgroud)