Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript node.js表搜索失败,承诺正在使用_Javascript_Node.js_Callback_Bluebird_Es6 Promise - Fatal编程技术网

Javascript node.js表搜索失败,承诺正在使用

Javascript node.js表搜索失败,承诺正在使用,javascript,node.js,callback,bluebird,es6-promise,Javascript,Node.js,Callback,Bluebird,Es6 Promise,我将在这里学到一些东西。我喜欢学习!提前感谢您的帮助 这里有30行Node.js JavaScript。这是一个标准的表格搜索。为了简单起见,我的“表”是一个16个整数的序列,从0到15。函数compareRow报告猜测的行r的行号是否低于、等于或高于对应于事务t的行;t需要行号r=t。(当然,代码越长就越复杂。)我已经删除了所有可以为您消除混乱的内容 异步问题(以及你们中的一些人在过去的问题中)鼓励我使用承诺。我的较长代码需要bluebird,并得到相同的结果。此代码使用JavaScript承

我将在这里学到一些东西。我喜欢学习!提前感谢您的帮助

这里有30行Node.js JavaScript。这是一个标准的表格搜索。为了简单起见,我的“表”是一个16个整数的序列,从0到15。函数compareRow报告猜测的行r的行号是否低于、等于或高于对应于事务t的行;t需要行号r=t。(当然,代码越长就越复杂。)我已经删除了所有可以为您消除混乱的内容

异步问题(以及你们中的一些人在过去的问题中)鼓励我使用承诺。我的较长代码需要bluebird,并得到相同的结果。此代码使用JavaScript承诺

'use strict'
function compareRow(r, t, low, high) {
  return new Promise(function(resolve, reject) {
    console.log('compareRow   r=' + r + '   t=' + t + '   low=' + low +
        '   high=', high)
    return resolve(r - t)
  })
}
function findRow(t) {
  let lo = 0, hi = 15, mid
  return new Promise(function(resolve, reject) {
    let mustBreak = false
    let count = 0, maxCount = 3
    do {
      mid = Math.floor((lo + hi) / 2)
      compareRow(mid, t, lo, hi)
      .then(function(ans, error) {
        console.log('findRow got compareRow(' + mid + ')=' + ans)
        if (error) { mustBreak = true; return reject(error) }
        else if (ans === 0) { mustBreak = true; return resolve(mid) }
        else if (ans < 0) lo = mid
        else if (ans > 0) hi = mid
      })
    } while (!mustBreak && ++count < maxCount)
  })
}
findRow(2)
.then(function(ans1, err1) {
  console.log('for findRow(2):   ans=' + ans1 + '   err=' + err1)
})
相反,我得到了:

compareRow   r=7   t=2   low=0   high= 15
compareRow   r=7   t=2   low=0   high= 15
compareRow   r=7   t=2   low=0   high= 15
findRow got compareRow(7)=5
findRow got compareRow(7)=5
findRow got compareRow(7)=5
看来

  • 执行进入compareRow(可能是及时的),但没有及时进入接收该答案的回调函数,导致无限循环
  • 或者至少,除了循环计数器将循环限制为三个周期外,该循环将是无限的
  • 假设循环停止,回调处理答案(findRow get compareRow(7)=5)并以循环运行的相同次数(三次)被调用似乎不是偶然的
  • 当回调代码运行时,处理输出的代码不再侦听
问题:

  • 是否有一种方法可以鼓励JavaScript调度器按照我的意愿处理代码?(这似乎是承诺的完全标准用例!)

  • 如何才能更好地编写此代码


编辑:措辞和问题变更;所有这些都与原始帖子具有相同的效果。删除了许多行代码。更正了一个语法错误。

@Bergi:做得好!如果你关心堆栈溢出中的点,请在回答中发布一些措辞,我会让你的成为公认的解决方案

我一开始说我会在这里学到一些东西。确实是这样。以下是一种反模式,因为JavaScript不会“为在其主体内创建的承诺”中断循环。不能在异步代码中使用此类循环

另一种方法是:“使用递归方法,您可以从异步承诺回调调用下一步。”

我还了解到,下面的工作。我不知道它是否可以被仿真,但在这段代码中已经证明了这一点

NOTE: This was sufficient in this code to start the promise chain.
return new Promise
.all([callNonrecursivePromiseFunc(1), callNonrecursivePromiseFunc(2)]
.then(function(result, error) {
  callRecursivePromiseFunction(result)
  .then(function(results, error) {
    // do something with results
  })
})
下面是我如何使用Bergi的建议来更改代码的。它起作用了。最后唷!同样,我已经删除了大量的错误检查等,以减少批量

'use strict'
let Promise = require('bluebird')
function compareRow(t, r, low, high) {
  return new Promise(function(resolve, reject) {
    console.log('compareRow   t=' + t + '   r=' + r + '   low=' + low +
        '   high=', high)
    let recursion = (r === null)  // distraction; skip it
    if (recursion) {
      r = Math.floor((low + high) / 2)
      if (r < t) low = r
      else if (r > t) high = r
      else if (r === t) return resolve(r)
      compareRow(t, null, low, high)  // recursion; this is the point
      .then(function(result, error) {
        return resolve(result)
      })
    } else {
      return resolve(r - t)  // distraction; skip it
    }
  })
}
function findRow(t) {
  return new Promise(function(resolve, reject) {
    let lo = 0, hi = 15
    console.log('findRow   t=' + t + '   lo=' + lo + '   hi=' + hi)
    return new Promise
    .all([compareRow(t, lo, lo, hi), compareRow(t, hi, lo, hi)])
    .then(function(result, error) {
      let ans = result[0]
      console.log('findRow got compareRow(' + lo + ')=' + ans)
      if (ans === 0) return resolve(lo)
      ans = result[1]
      console.log('findRow got compareRow(' + hi + ')=' + ans)
      if (ans === 0) return resolve(hi)
      compareRow(t, null, lo, hi)  // this is a recursive call
      .then(function(result, error) {
        return resolve(result)
      })
    })
  })
}
findRow(2)
.then(function(ans1, err1) {
  console.log('for findRow(2):   ans=' + ans1 + '   err=' + err1)
})
“严格使用”
让承诺=要求(‘蓝鸟’)
功能比较器低(t、r、低、高){
返回新承诺(功能(解决、拒绝){
log('compareRow t='+t+'r='+r+'low='+low+
‘高=’,高)
让递归=(r==null)//分散注意力;跳过它
if(递归){
r=数学楼层((低+高)/2)
如果(rt)高=r
else if(r==t)返回resolve(r)
compareRow(t,null,low,high)//递归;这就是重点
.then(函数(结果、错误){
返回解析(结果)
})
}否则{
返回resolve(r-t)//分心;跳过它
}
})
}
函数findRow(t){
返回新承诺(功能(解决、拒绝){
设lo=0,hi=15
log('findRow t='+t+'lo='+lo+'hi='+hi)
回报新的承诺
.all([compareRow(t,lo,lo,hi),compareRow(t,hi,lo,hi)])
.then(函数(结果、错误){
设ans=结果[0]
log('findRow获得了compareRow('+lo+')='+ans)
如果(ans==0)返回解析(lo)
ans=结果[1]
log('findRow获得了compareRow('+hi+')='+ans)
如果(ans==0)返回解析(hi)
compareRow(t,null,lo,hi)//这是一个递归调用
.then(函数(结果、错误){
返回解析(结果)
})
})
})
}
芬德罗(2)
.then(函数(ans1,err1){
log('for findRow(2):ans='+ans1+'err='+err1)
})
评论:

  • 请注意使用蓝鸟承诺。这段代码因JavaScript承诺而失败
  • 使用递归方法:
    • 对变量mustBreak的需求消失了。那是一个“嘀嗒”
    • 每次我调用“resolve”或“reject”,我都与声明处于同一范围内。那是一个“嘀嗒”
    • 在任何时候我都不能在循环中定义函数。杰希特更快乐。那是一个“嘀嗒”
  • 这段代码有一些不受欢迎的复杂性,因为我使用compareRow用于递归和非递归目的。哎呀。我在这里不够优雅

  • 伯吉:干得好!如果你关心堆栈溢出中的点,请在回答中发布一些措辞,我会让你的成为公认的解决方案

    我一开始说我会在这里学到一些东西。确实是这样。以下是一种反模式,因为JavaScript不会“为在其主体内创建的承诺”中断循环。不能在异步代码中使用此类循环

    另一种方法是:“使用递归方法,您可以从异步承诺回调调用下一步。”

    我还了解到,下面的工作。我不知道它是否可以被仿真,但在这段代码中已经证明了这一点

    NOTE: This was sufficient in this code to start the promise chain.
    return new Promise
    .all([callNonrecursivePromiseFunc(1), callNonrecursivePromiseFunc(2)]
    .then(function(result, error) {
      callRecursivePromiseFunction(result)
      .then(function(results, error) {
        // do something with results
      })
    })
    
    下面是我如何使用Bergi的建议来更改代码的。它起作用了。最后唷!同样,我已经删除了大量的错误检查等,以减少批量

    'use strict'
    let Promise = require('bluebird')
    function compareRow(t, r, low, high) {
      return new Promise(function(resolve, reject) {
        console.log('compareRow   t=' + t + '   r=' + r + '   low=' + low +
            '   high=', high)
        let recursion = (r === null)  // distraction; skip it
        if (recursion) {
          r = Math.floor((low + high) / 2)
          if (r < t) low = r
          else if (r > t) high = r
          else if (r === t) return resolve(r)
          compareRow(t, null, low, high)  // recursion; this is the point
          .then(function(result, error) {
            return resolve(result)
          })
        } else {
          return resolve(r - t)  // distraction; skip it
        }
      })
    }
    function findRow(t) {
      return new Promise(function(resolve, reject) {
        let lo = 0, hi = 15
        console.log('findRow   t=' + t + '   lo=' + lo + '   hi=' + hi)
        return new Promise
        .all([compareRow(t, lo, lo, hi), compareRow(t, hi, lo, hi)])
        .then(function(result, error) {
          let ans = result[0]
          console.log('findRow got compareRow(' + lo + ')=' + ans)
          if (ans === 0) return resolve(lo)
          ans = result[1]
          console.log('findRow got compareRow(' + hi + ')=' + ans)
          if (ans === 0) return resolve(hi)
          compareRow(t, null, lo, hi)  // this is a recursive call
          .then(function(result, error) {
            return resolve(result)
          })
        })
      })
    }
    findRow(2)
    .then(function(ans1, err1) {
      console.log('for findRow(2):   ans=' + ans1 + '   err=' + err1)
    })
    
    “严格使用”
    让承诺=要求(‘蓝鸟’)
    功能比较器低(t、r、低、高){
    返回新承诺(功能(解决、拒绝){
    log('compareRow t='+t+'r='+r+'low='+low+
    ‘高=’,高)
    让递归=(r==null)//分散注意力;跳过它
    if(递归){
    r=数学楼层((低+高)/2)
    如果(rt)高=r
    else if(r==t)返回resolve(r)
    compareRow(t,null,low,high)//重复