В то время как обещания и обратные вызовы хорошо работают во многих ситуациях, боль в задней части выражает нечто вроде:
if (!name) {
name = async1();
}
async2(name);
. В итоге вы пройдете через async1
; проверьте, не определено ли name
или нет, и соответственно вызовите обратный вызов.
async1(name, callback) {
if (name)
callback(name)
else {
doSomething(callback)
}
}
async1(name, async2)
Хотя в в порядке хорошо , это раздражает, когда у вас много подобных случаев и обработка ошибок. Вы можете проверить проект здесь . Fibers
помогает в решении проблемы. var Fiber = require('fibers')
function async1(container) {
var current = Fiber.current
var result
doSomething(function(name) {
result = name
fiber.run()
})
Fiber.yield()
return result
}
Fiber(function() {
var name
if (!name) {
name = async1()
}
async2(name)
// Make any number of async calls from here
}
К сожалению, cubature
не отправляет заголовки в inst/include
, поэтому вы должны брать их у них и делать что-то вроде этого в своем коде:
typedef void (*integrand) (unsigned ndim, const double *x, void *,
unsigned fdim, double *fval);
int adapt_integrate(
unsigned fdim, integrand f, void *fdata,
unsigned dim, const double *xmin, const double *xmax,
unsigned maxEval, double reqAbsError, double reqRelError,
double *val, double *err)
{
typedef int (*Fun)(unsigned,integrand,void*,unsigned,
const double*,const double*, unsigned, double, double, double*, double*) ;
Fun fun = (Fun) R_GetCCallable( "cubature", "adapt_integrate" ) ;
return fun(fdim,f,fdata,dim,xmin,xmax,maxEval,reqAbsError, reqRelError,val,err);
}
Это может быть хорошей идеей чтобы обсудить с сопровождающим cubature
, что он отправляет объявления в inst/include
, так что вам нужно будет использовать LinkingTo
.
Не видел этого вопроса раньше, и похоже, что @Romain обратился к нему.
Для полноты рабочий пример того, как это сделать, когда все стороны играют, предоставляется xts
и RcppXts
. В xts
мы делаем это (около десяти функций) в файле (source) inst/include/xtsAPI.h
:
SEXP attribute_hidden xtsLag(SEXP x, SEXP k, SEXP pad) {
static SEXP(*fun)(SEXP,SEXP,SEXP) = NULL;
if (fun == NULL)
fun = (SEXP(*)(SEXP,SEXP,SEXP)) R_GetCCallable("xts","lagXts");
return fun(x, k, pad);
}
вместе с обычной работой R_registerRoutines
и R_RegisterCCallable
.
В RcppXts
это подбирается (в модуле Rcpp) как
function("xtsLag",
&xtsLag,
List::create(Named("x"), Named("k"), Named("pad")),
"Extract the coredata from xts object");
, который работает очень хорошо. Кто-то сделал мне выговор, чтобы написать xts
сторону более компактно (поскольку if NULL
является ложным), который я получу ... в конце концов.
Этот вопрос сейчас три года, но я хочу отметить, что многомерная интеграция с Rcpp может быть проще теперь, когда доступна библиотека RcppNumerical: https://github.com/yixuan/RcppNumerical
Подпрограммы для вычислений интегралов основаны на кубинском пакете Томаса Хана и также доступны в библиотеке R2Cuba на CRAN, поэтому, если вы можете согласиться с использованием кубинских процедур над функцией adaptIntegrate()
из Cubature, этот пакет может представлять интерес.