Nel tentativo di smettere di scrivere un sacco di codice duplicato, sto cercando di non aprire le chiamate. Preferirei preferibilmente passare solo le funzioni da un livello superiore. Come questo.Scrivere promesse senza aprire quindi chiama
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)))
}
Tuttavia, il codice sopra riportato non funziona. Il test seguente mostra che non è possibile passare una funzione asincrona bound
promisifyAll
. Il motivo è che il valore di allora è passato in queste promesse che li induce ad agire come argomento successivo nella chiamata, per queste funzioni che significa che attivano come callback, motivo per cui il primo errore di test è fuori con Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
in moka.
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")
})
})
})
})
Quali funzioni esistono, o il modo di avvolgere la funzione associata consentirebbe di lavorare con le promesse in questo modo?
Aggiornamento:
Sto cercando una libreria di suite di involucri funzione (lodash ha un sacco di loro) che permettono una facile interfaccia di partialing o binding from my question earlier o di confezionamento funzioni per passare ad una then
o correre all'interno di un Promise.reduce
. In questo modo concatenare le promesse è davvero facile.
Idealmente, voglio solo sapere come far funzionare la linea, un modo di avvolgerla in modo che quando viene passato un risultato dall'altra, lo ignori. O un'alternativa raccomandata.
.then(_.bind(fsExtra.mkdirsAsync, fsExtra, dstDir))
Davvero difficile capire esattamente cosa stai chiedendo - puoi chiarire ulteriormente. Una funzione promessa (in qualche modo per definizione) restituisce una promessa e non utilizza più una richiamata. Se lo chiami, restituirà una promessa che viene risolta solo quando viene eseguita l'operazione asincrona sottostante. Inoltre, se si desidera un'operazione seriale, non un'operazione parallela, è necessario passare un riferimento di funzione a un gestore '.then()', non al valore di ritorno dell'esecuzione di qualche funzione (a meno che il valore restituito sia esso stesso una funzione che è ciò che vuoi chiamato in sequenza). – jfriend00
Purtroppo, la modifica non ha aiutato molto a capire il problema.C'è una serie di descrizioni di problemi diversi confusi. Vedo almeno 1. il test dell'unità non è stato costruito correttamente e si traduce in un timeout (non un'affermazione fallita) 2. fraintendimento del funzionamento di 'bind'. in realtà per esempio last' then' handler '_.bind (fsExtra.linkAsync ...' riceve il risultato della precedente promessa in chain.Ma 'fsExtra.linkAsync' lo ottiene come terzo parametro (dopo' dstPath') –
I don Forse ti basterà eseguire il backup e descrivere una sequenza specifica di operazioni che vuoi scriptare e poi chiedere come è il modo più efficiente per scriverlo? Sembra che tu stia cercando di fare una sorta di domanda generica, ma usando un insieme di codice davvero complicato con un sacco di problemi per cercare di descrivere il problema e ci stai perdendo in questa complessità. Puoi ridurre il problema ad un esempio molto più semplice? – jfriend00