gpt4 book ai didi

javascript - 展平一个_very_嵌套密集型函数 : how to?

转载 作者:搜寻专家 更新时间:2023-11-01 00:45:29 25 4
gpt4 key购买 nike

我是 JsonRestStores 的作者.我已经把这个问题推迟了太久了。这是一个将赢得“年度最愚蠢的缩进函数”奖的函数。

主要的棘手问题是有一个闭包变量被改变的点:

body[ self.idProperty ] = params[ self.idProperty ];

还有一个让事情变得有趣的“如果”。

那么...有没有一种优雅的方法可以将这个函数变成看起来不太像带有两个戳的箭头的东西?如果是这样,您能否提供一个实现示例?

  _makePostAppend: function( params, body, options, next ){

var self = this;
var body;

if( typeof( next ) !== 'function' ) next = function(){};

// Check that the method is implemented
if( ! self.handlePostAppend ){
self._sendError( next, new self.NotImplementedError( ) );
return;
}

// Check the IDs
self._checkParamIds( params, body, false, function( err ){
self._sendErrorOnErr( err, next, function(){

self.schema.validate( body, function( err, body, errors ) {
self._sendErrorOnErr( err, next, function(){

if( errors.length ){
self._sendError( next, new self.UnprocessableEntityError( { errors: errors } ) );
} else {

// Fetch the doc
self.execAllDbFetch( params, body, options, function( err, fullDoc ){
self._sendErrorOnErr( err, next, function(){


self.extrapolateDoc( params, body, options, fullDoc, function( err, doc) {
self._sendErrorOnErr( err, next, function(){

self._castDoc( doc, function( err, doc) {
self._sendErrorOnErr( err, next, function(){

// Actually check permissions
self.checkPermissionsPostAppend( params, body, options, doc, fullDoc, function( err, granted ){
self._sendErrorOnErr( err, next, function(){

if( ! granted ){
self._sendError( next, new self.ForbiddenError() );
} else {

// Clean up body from things that are not to be submitted
//if( self.schema ) self.schema.cleanup( body, 'doNotSave' );
self.schema.cleanup( body, 'doNotSave' );

// Paranoid check
// Make sure that the id property in the body does match
// the one passed as last parameter in the list of IDs
body[ self.idProperty ] = params[ self.idProperty ];

self.execPostDbAppend( params, body, options, doc, fullDoc, function( err, fullDocAfter ){
self._sendErrorOnErr( err, next, function(){

self.extrapolateDoc( params, body, options, fullDocAfter, function( err, doc) {
self._sendErrorOnErr( err, next, function(){

self._castDoc( fullDocAfter, function( err, docAfter) {
self._sendErrorOnErr( err, next, function(){

// Remote request: set headers, and send the doc back (if echo is on)
if( self.remote ){
if( self.echoAfterPostAppend ){

self.prepareBeforeSend( docAfter, function( err, docAfter ){
self._sendErrorOnErr( err, next, function(){

self.afterPostAppend( params, body, options, doc, fullDoc, docAfter, fullDocAfter, function( err ){
self._sendErrorOnErr( err, next, function(){

self._res.json( 200, docAfter );

});
});
})
})
} else {

self.afterPostAppend( params, body, options, doc, fullDoc, docAfter, fullDocAfter, function( err ){
self._sendErrorOnErr( err, next, function(){

self._res.send( 204, '' );

});
});

}

// Local request: simply return the doc to the asking function
} else {

self.prepareBeforeSend( docAfter, function( err, docAfter ){
self._sendErrorOnErr( err, next, function(){

self.afterPostAppend( params, body, options, doc, fullDoc, docAfter, fullDocAfter, function( err ){
self._sendErrorOnErr( err, next, function(){

next( null, docAfter, self.idProperty );

})
})

})
})
}

})
});

});
})


}) // err
}) // execPostDbAppend

} // granted


})
})

})
})

})
})

}) // err
}) // checkPermissionsPostAppend

} // errors.length

}) // err
}) // self.validate

}) // err
}) // self.validate
},

最佳答案

如果我像您一样编写代码,我更愿意使用 async图书馆,它是waterfall函数,这样我就不必用它的 promise 版本包装异步 API。这非常简单。 Promises 也很棒,@Esailija 的回答没有任何问题,但我个人认为这更容易实现并且可读性也一样:

var async = require('async');

var _makePostAppend = function (params, body, options, next) {
var self = this, body;
if (typeof(next) !== 'function') next = function () { };

// Check that the method is implemented
if (!self.handlePostAppend) {
self._sendError(next, new self.NotImplementedError());
return;
}

async.waterfall([
function (cb) {
// Check the IDs
self.checkParamIds(params, body, false, cb);
},
function (cb) {
self.schema.validate(body, cb);
},
function (body, errors, cb) {
if (errors.length) cb(new self.UnprocessableEntityError({ errors: errors }));
// Fetch the doc
self.execAllDbFetch(params, body, options, cb);
},
function (fullDoc, cb) {
self.extrapolateDoc(params, body, options, fullDoc, function (err, doc) {
cb(err, fullDoc, doc);
});
},
function (fullDoc, doc, cb) {
self._castDoc(doc, function (err, doc) {
cb(err, fullDoc, doc);
});
},
function (fullDoc, doc, cb) {
// Actually check permissions
self.checkPermissionsPostAppend(params, body, options, doc, fullDoc, function (err, granted) {
cb(err, fullDoc, doc, granted);
});
},
function (fullDoc, doc, granted, cb) {
if (!granted) cb(new self.ForbiddenError());

// Clean up body from things that are not to be submitted
//if( self.schema ) self.schema.cleanup( body, 'doNotSave' );
self.schema.cleanup(body, 'doNotSave');

// Paranoid check
// Make sure that the id property in the body does match
// the one passed as last parameter in the list of IDs
body[self.idProperty] = params[self.idProperty];

self.execPostDbAppend(params, body, options, doc, fullDoc, function (err, fullDocAfter) {
cb(err, fullDoc, fullDocAfter);
});
},
function (fullDoc, fullDocAfter, cb) {
self.extrapolateDoc(params, body, options, fullDocAfter, function (err, doc) {
cb(err, fullDoc, doc, fullDocAfter);
});
},
function (fullDoc, doc, fullDocAfter, cb) {
self._castDoc(fullDocAfter, function (err, docAfter) {
cb(err, fullDoc, doc, fullDocAfter, docAfter);
});
}
], function (err, fullDoc, doc, fullDocAfter, docAfter) {
self._sendErrorOnErr(err, next, function () {
// Remote request: set headers, and send the doc back (if echo is on)
if (self.remote) {
if (self.echoAfterPostAppend) {
async.waterfall([
function (cb) {
self.prepareBeforeSend(docAfter, cb);
},
function (docAfter, cb) {
self.afterPostAppend(params, body, options, doc, fullDoc, docAfter, fullDocAfter, cb)
}
], function (err, docAfter) {
self._sendErrorOnErr(err, next, function () {
self._res.json(200, docAfter);
});
});
} else {
self.afterPostAppend(params, body, options, doc, fullDoc, docAfter, fullDocAfter, function (err) {
self._sendErrorOnErr(err, next, function () {
self._res.send(204, '');
});
});
}

// Local request: simply return the doc to the asking function
} else {
async.waterfall([
function (cb) {
self.prepareBeforeSend(docAfter, function (err, docAfter) {
cb(err, doc, fullDoc, fullDocAfter, docAfter);
})
},
function (doc, fullDoc, fullDocAfter, docAfter, cb) {
self.afterPostAppend(params, body, options, doc, fullDoc, docAfter, fullDocAfter, function (err) {
cb(err, docAfter);
});
}
], function (err, docAfter) {
self._sendErrorOnErr(err, next, function () {
next(null, docAfter, self.idProperty);
});
});
}
});
});
};

或者更好的是,我使用了@Esailija 的回答中的范围界定技巧:

var async = require('async');

var _makePostAppend = function (params, body, options, next) {
var _self = this, _body, _fullDoc, _doc, _docAfter, _fullDocAfter;
if (typeof(next) !== 'function') next = function () { };

// Check that the method is implemented
if (!_self.handlePostAppend) {
_self._sendError(next, new _self.NotImplementedError());
return;
}

async.waterfall([
function (cb) {
// Check the IDs
_self.checkParamIds(params, _body, false, cb);
},
function (cb) {
_self.schema.validate(_body, cb);
},
function (body, errors, cb) {
if (errors.length) cb(new _self.UnprocessableEntityError({ errors: errors }));
// Fetch the doc
_self.execAllDbFetch(params, body, options, cb);
},
function (fullDoc, cb) {
_fullDoc = fullDoc;
_self.extrapolateDoc(params, _body, options, fullDoc, db);
},
function (doc, cb) {
_self._castDoc(doc, cb);
},
function (doc, cb) {
_doc = doc;
// Actually check permissions
_self.checkPermissionsPostAppend(params, _body, options, doc, _fullDoc, cb);
},
function (granted, cb) {
if (!granted) cb(new _self.ForbiddenError());

// Clean up body from things that are not to be submitted
//if( self.schema ) self.schema.cleanup( body, 'doNotSave' );
_self.schema.cleanup(_body, 'doNotSave');

// Paranoid check
// Make sure that the id property in the body does match
// the one passed as last parameter in the list of IDs
_body[_self.idProperty] = params[_self.idProperty];

_self.execPostDbAppend(params, _body, options, _doc, _fullDoc, cb);
},
function (fullDocAfter, cb) {
_fullDocAfter = fullDocAfter;
_self.extrapolateDoc(params, _body, options, fullDocAfter, cb);
},
function (doc, cb) {
_doc = doc;
_self._castDoc(_fullDocAfter, cb);
}
], function (err, docAfter) {
_self._sendErrorOnErr(err, next, function () {
// Remote request: set headers, and send the doc back (if echo is on)
if (_self.remote) {
if (_self.echoAfterPostAppend) {
async.waterfall([
function (cb) {
_self.prepareBeforeSend(docAfter, cb);
},
function (docAfter, cb) {
_self.afterPostAppend(params, _body, options, _doc, _fullDoc, docAfter, _fullDocAfter, cb)
},
function (cb) {
_self._res.json(200, docAfter);
cb();
}
], function (err, results) {
_self._sendErrorOnErr(err, next);
});
} else {
_self.afterPostAppend(params, _body, options, _doc, _fullDoc, docAfter, _fullDocAfter, function (err) {
_self._sendErrorOnErr(err, next, function () {
_self._res.send(204, '');
});
});
}

// Local request: simply return the doc to the asking function
} else {
async.waterfall([
function (cb) {
_self.prepareBeforeSend(docAfter, cb);
},
function (docAfter, cb) {
_docAfter = docAfter;
_self.afterPostAppend(params, _body, options, _doc, _fullDoc, docAfter, _fullDocAfter, cb);
}
], function (err) {
_self._sendErrorOnErr(err, next, function () {
next(null, _docAfter, _self.idProperty);
});
});
}
});
});
};

关于javascript - 展平一个_very_嵌套密集型函数 : how to?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19874967/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com