Starając się przerwać pisanie wielu duplikatów kodu, próbuję nie otwierać, a następnie dzwonić. Preferowałbym jedynie przekazywanie funkcji z poziomu najwyższego poziomu. Lubię to.Pisząc obietnice bez otwierania, a następnie dzwoniąc pod numer
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)))
}
Jednak powyższy kod nie działa. Poniższy test pokazuje, że nie można przekazać funkcji asynchronicznej bound
promisifyAll
. Powodem jest to, że wartość ta jest przekazywana do tych obietnic, co powoduje, że stają się one następnym argumentem w wywołaniu, ponieważ te funkcje oznaczają, że są uruchamiane jako wywołania zwrotne, dlatego pierwszy błąd testowy jest wyświetlany z mokrą wersją z Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
.
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")
})
})
})
})
Jakie funkcje istnieją lub sposób owijania oprawionej funkcji pozwoliłby na pracę z obietnicami w ten sposób?
Aktualizacja:
szukam biblioteki pakietu owijarki funkcyjnych (lodash ma kilka z nich), które pozwalają na łatwy interfejs partialing lub binding from my question earlier lub owijania funkcji przejść do then
lub biegu w obrębie Promise.reduce
. W ten sposób spieranie obietnic jest naprawdę łatwe.
Idealnie po prostu chcę wiedzieć, jak uruchomić linię, sposób owijania jej tak, aby po przejściu z niej wynik zignorował ją. Lub zalecana alternatywa.
.then(_.bind(fsExtra.mkdirsAsync, fsExtra, dstDir))
Naprawdę trudno dokładnie zrozumieć, o co prosisz - czy możesz wyjaśnić dalej. Funkcja promisified (nieco z definicji) zwraca obietnicę i nie używa już wywołania zwrotnego. Jeśli ją wywołasz, zwróci obietnicę, która zostanie rozwiązana tylko wtedy, gdy wykonana zostanie podstawowa operacja asynchroniczna. Ponadto, jeśli chcesz operację szeregową, a nie operację równoległą, musisz przekazać odwołanie do funkcji do obsługi '.then()', a nie do zwracanej wartości wykonywania niektórych funkcji (chyba że ta wartość zwracana sama w sobie jest funkcją, która jest funkcją chcesz zadzwonić w sekwencji). – jfriend00
Niestety, edycja nie pomogła w zrozumieniu problemu.Istnieje wiele różnych pomieszanych opisów problemów. Widzę co najmniej 1. test jednostkowy nie jest poprawnie zbudowany i skutkuje przekroczeniem limitu czasu (a nie błędnym stwierdzeniem) 2. nieporozumieniem, jak działa "bind". w rzeczywistości na przykład ostatni 'then' handler' _.bind (fsExtra.linkAsync ... 'otrzymuje wynik poprzedniej obietnicy w łańcuchu, ale' fsExtra.linkAsync' pobiera ją jako trzeci parametr (po 'dstPath') –
Może po prostu zarchiwizujesz i opisz konkretną sekwencję operacji, które chcesz skryptować, a następnie zapytasz, jak najskuteczniejszy sposób to napisać? Wygląda na to, że próbujesz zadać jakieś ogólne pytanie, ale używając naprawdę skomplikowany zestaw kodu z mnóstwem problemów, aby spróbować opisać problem i tracisz nas w tej złożoności.Czy możesz zredukować problem do znacznie prostszego przykładu? – jfriend00