2016-09-21 44 views
1

我目前正在使用一个将被集成到用户自己的Web服务器中的API /路由器。我的代码将完成所需的工作,但也允许用户在之后实现自己的逻辑,例如以下片段:myApi.on('action', (err, result, req, res) => {/*user's logic here*/})如何promisify一个不包含回调参数的函数?

按照设计,如果用户决定重写默认行为并实现自己的逻辑,我的代码将不会结束响应。这是为了允许请求和响应在用户需要时进入下一个中间件功能。

我想要的控制流程是:

  1. 运行我的初始路径逻辑

  2. 运行用户的自定义逻辑

  3. 控制传递给下一个中间件的功能,如果反应还没有已结束

我的问题出现时用户想要实现任何异步逻辑。在将控制权交给下一个中间件功能之前,我无法让用户的自定义逻辑结束。我相信这是因为我设置的界面。我希望用户尽可能做一些小工作。这意味着我不希望向用户传递一些他们需要在其逻辑的每个端点上调用的功能(因为我的路由器涉及许多不同的路由),因此不需要传递相应的功能callback()next()

我已经看过承诺包装如promisify-node,但他们似乎只能包装函数,将回调作为他们的最终参数。我也考虑要求用户从自定义实现中返回一个承诺,但这违背了我不希望繁忙/样板代码的愿望。

有什么方法可以使用承诺 - 或任何其他构造 - 我可以处理这个异步问题,而不必痛苦用户?

+0

如何定义请求结束? – Amit

+0

@Amit,似乎我切换了请求和响应。我会通过检查res.finished标签来检查**响应**是否完成。 – TheKingOfTyrants

回答

1

不,你不能promisify一个函数,不采取回调。这样的功能或者不是异步的,或者不能让你知道什么时候完成 - 你运气不好。

我的问题出现在用户想要实现任何异步逻辑时。

只需要用户传递一个函数来返回一个承诺,如果他想实现异步的东西。它可能会做的他也不得不与承诺的工作:-)

const myApi = { 
    on(name, fn) { 
     Promise.resolve(result) // or whenever you need to run the user logic 
     .then(result => 
      fn(req, result) // or whatever you want to pass 
     ) 
     .then(customresult => { 
      res.write(customresult); // or whatever you want to do with its result 
     }); 
    } 
}; 

myApi.on('action', (req, result) => { 
    // user's logic here 
    // throw exceptions 
    // return values 
    // return promises for values 
    // or whatever the user needs to do 
}) 
0

如果我知道你会检查值的用户自定义函数返回问题的青睐。如果它是一个承诺,如对象,那么你可以等待它解决之后继续前进。这相当于将next函数传递给用户的自定义中间件。

在您的例子中,用户(S)将使用自己的API,像这样:

myApi.on('action', (err, result, req, res) => { 
    return myPromiseAwareAsyncFunction(); 
}) 

并在代码:

let userMiddleWare = lookupNextActionHandler(); 
let result = userMiddleWare(err, result, req, res); 
// Wrap any value (promise or not) in a promise 
Promise.resolve(result) 
    .then(result => { 
    // Move on to next middle ware 
    }) 
    .catch(error => { 
    console.error(error); 
    process.exit(1); // Or what ever you use 
        // to end the middle ware chain. 
    }); 

如果你想同时提供承诺一个next回调你可以这样做:

let userMiddleWare = lookupNextActionHandler(); 
new Promise((resolve, reject) => { 
    function next(err) { 
    if (err) { 
     reject(err); 
    } else { 
     resolve(); 
    } 
    } 
    let result = userMiddleWare(err, result, req, res, next); 
    Promise.resolve(result).then(resolve).catch(reject); 
}) 
.then(result => { 
    // Move on to next middle ware 
}) 
.catch(error => { 
    console.error(error); 
    process.exit(1); // Or what ever you use 
        // to end the middle ware chain. 
}); 

由于承诺只能处理一个解决方案,并且在设置后会忽略更多咒语,这将会起作用,并且用户使用哪个(next或返回承诺)将起作用。

相关问题