2017-07-31 46 views
0

我正在使用hapi的服务器上工作,并执行node-rules的规则。当我没有返回值时将回调转换为Promise

我有一个回调,从node-rulesR.execute方法调用。作为执行callback的结果,我需要从exec方法返回Promise

代码

const callback = data => { 
    const {matchPath, result} = data 
    descision.setMatchPath(matchPath) 
    if (!result) { 
    descision.addMessage(
     'No match could be found in the rules provided, either incorrect or non-matching information was provided' 
    ) 
    } 
} 

function exec (input) { 
    const {medicineType, facts: data} = input 
    const R = new RuleEngine() 
    R.register(rules) 
    if (medicineType !== 'generic') { 
    const facts = { 
     data 
    } 
    R.execute(facts, callback) 
    } 
} 

我从源代码中发现R.execute不返回任何东西,我可以使用。我注意到在execute中递归调用function here,但没有回调就不会终止。

如何将其转换为返回Promise的函数?

+0

你为什么要返回,而不是用'callback'功能工作了'Promise'? – ishmaelMakitla

+0

@ishmaelMakitla'hapi'服务器正在等待规则引擎的结果,以便它可以响应一个值,所以我需要返回一个'Promise'。 – vamsiampolu

+0

'execute'可能不会返回任何东西,但它会调用给它的'callback'。这还不够吗? – Bergi

回答

0

在浏览过一些答案的其他问题,我想起了$.deferredQ.defer API,我发现,类似于他们的解决方案:

  1. 创建递延

  2. 传递推迟到回调

  3. 使用deferred和解决的承诺

  4. ,最重要的是,返回由deferred

创建promise我不想一个自定义的承诺的实现或猴 - 修补Promise API。如果后者不是问题,npm上有几个模块可以做到这一点,并且可以填充Promise.defer

defer功能是from here

代码现在看起来像:

/* eslint-disable promise/param-names */ 
function defer() { 
    let resolve, reject 
    const promise = new Promise(function (...args) { 
    resolve = args[0] 
    reject = args[1] 
    }) 
    return {resolve, reject, promise} 
} 

/* eslint-enable promise/param-names */ 

const makeCallback = deferred => data => { 
    const {matchPath, result} = data 
    descision.setMatchPath(matchPath) 
    if (!result) { 
    descision.addMessage(
     'No match could be found in the rules provided, either incorrect or non-matching information was provided' 
    ) 
    } 
    deferred.resolve(descision) 
} 

function exec (input) { 
    const {medicineType, facts: data} = input 
    const R = new RuleEngine() 
    R.register(rules) 
    if (lenderType !== 'generic') { 
    const facts = { 
     data 
    } 
    const deferred = defer() 
    const callback = makeCallback(deferred) 
    R.execute(facts, callback) 
    return deferred.promise 
    } 
} 
+0

关于你的编辑,你误会了'等待'的工作方式。它需要得到一个承诺,带回调的'R.execute'不会返回一个。 – Bergi

+0

@Bergi我同意它不应该工作,因为没有'R.execute'或'callback'的返回值,并且没有使用Promise,这对我来说也是一个问题。该库使用'process.nextTick'调用回调函数,这是等待直到回调被调用的可能原因。 – vamsiampolu

+0

是的。请使用'new Promise'构造函数来修复它。 – Bergi

0

不知道如果我理解正确,但这样的事情可能会做

function exec(input) { 
    const { medicineType, facts: data } = input 
    const R = new RuleEngine() 
    R.register(rules) 

    return new Promise(function(resolve, reject) { 
     if (medicineType !== 'generic') { 
      const facts = { 
       data 
      } 
      R.execute(facts, function(data) { 
       const { matchPath, result } = data 
       descision.setMatchPath(matchPath) 
       if (!result) { 
        descision.addMessage(
         'No match could be found in the rules provided, either incorrect or non-matching information was provided' 
        ) 
       } 
       resolve('<return here whatever you want>') 
       // or 
       // reject('<return some error>') 
      }); 
     } else { 
      reject('<return some error>') 
     } 
    }) 
} 
相关问题