为什么我无法通过从数组中调用其解析器来解决承诺?

时间:2016-01-24 01:07:37

标签: javascript promise

代码可以在我的回购here找到,但我会粘贴:

function asyncQueue() {
  'use strict'
  let i = -1
  let j = 0
  const resolvers = []

  function put (p) {
    if (!p.then) 
      p = Promise.resolve(p)

    if (resolvers[j] instanceof Array) {
      const done = resolvers[j][0]
      const fail = resolvers[j][1]
      p.then( a => done(a) ).catch( e => fail(e) )
    } else {
      resolvers[j] = p
    }

    ++j
  }

  function get() {
    ++i
    if (resolvers[i] instanceof Promise) 
      return resolvers[i]

    return new Promise( (resolve, reject) => resolvers[i] = [resolve, reject] )
  }

  return { 
    get: get, 
    put: put
  }
}

如果我们改变Put函数,那么就像Node 5.4一样:

    if (resolvers[j] instanceof Array) {
      p.then( a => resolvers[j][0](a) ).catch( e => resolvers[j][1](e) )
    } else {
      resolvers[j] = p
    }

那些解析器属于永远的承诺。 WAT?!

我花了一个小时试图弄清楚我到底做错了什么,但后来决定绑定解析器参考并继续前进。有没有人知道为什么从数组poo poos内部调用函数?我观察到a是我们期望的值,但是以这种方式将它传递给解析器会使所有者Promise处于挂起状态,就像我从未解雇过解析器一样。

2 个答案:

答案 0 :(得分:1)

** 编辑:错别字是一个红色的鲱鱼,所以我添加了一个新答案,回答了你的实际问题,为什么承诺没有得到解决 **

回答你的问题: 第12行和第13行有拼写错误:

const done = resolver[j][0]
const fail = resolver[j][1]

如果将这些更改为resolvers(添加s),则测试将在节点5.5上传递

你可能认为它没有解决,因为如果你要说:

q = asyncQueue()
x = q.get()
q.put(1)
x.then(value => console.log(value))

您的控制台有两行:

Promise { <pending> }
1

因为最后一行实际上也返回了一个新的promise,直到控制台记录返回值的默认行为之后才会解析。

答案 1 :(得分:0)

好的,既然我更了解你的问题并且错别字被解决了,我会再次尝试回答。

  

有没有人知道为什么要从数组poo poos中调用内联函数?

它与j上的闭包有关。

在第一个示例中,您要在resolvers[j][0]结尾处的++j之前解析.put() 同步

当你“内联”对解析器的访问权限(我的意思是,使用j键访问<{1}} 里面的解析器承诺,它们正在发生异步(就像在下一个滴答类型中), resolvers之后,所以你正在访问一个空的数组索引和将其称为一种功能。

它“无声地失败”或者从未解决的原因是,put中的catch只会导致另一个“函数未定义”错误,这可能会被捕获,除了++j创建的永远不会被引用再次被抛弃,因此使用p创建的承诺永远无法解决或拒绝。