代码可以在我的回购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处于挂起状态,就像我从未解雇过解析器一样。
答案 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
创建的承诺永远无法解决或拒绝。