2016-01-24 59 views
-1

的代碼可以在我的回購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 
    } 
} 

美中不足的是,在作爲節點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?

我花了一個小時試圖弄清楚我做錯了什麼,但後來決定只是綁定resolver refs並繼續前進。任何人都不知道爲什麼從數組poo poos內聯調用函數?我注意到a是我們期望的值,但是通過這種方式將它傳遞給解析器會使所有者Promise處於未決狀態,就好像我從未解僱過解析器。

+1

什麼是asyncQueue?它應該做什麼? – elclanrs

+1

WAT它是......它就像整個「你不應該做的」在一段代碼中。 :) – Microfed

+1

你爲什麼不喜歡亞馬遜這麼多... –

回答

1

** 編輯:錯別字是一個紅鯡魚,所以我增加了一個新的答案回答您的實際問題,爲什麼承諾沒有得到解決 **

要回答你的問題: 你有一個上線12和13錯字:

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

如果你改變那些resolvers(添加一個或多個),你的測試通過對節點5.5

你也許會想它沒有資源olve,因爲如果你是在說:

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

您的控制檯將有兩條線:

Promise { <pending> } 
1 

因爲最後一行實際上是返回一個新的承諾,以及,這不會解決,直至控制檯後記錄返回值的默認行爲。

+0

感謝您檢測錯別字,但您是否從陣列中調用了內聯解析器?錯別字只是拼寫錯誤,我之前使用正確的變量名稱的代碼,並得到了輸出,你很好。但是,如果我以這種方式調用解析器 - > p.then(a => resolver [j] [0](a)).catch(e => resolver [j] [1](e))< - I沒有得到那個輸出,事實上,從未記錄過,承諾還在等待 –

+0

爲了清楚起見,我編輯了我的帖子,並指出錯別字不是導致問題的原因 –

0

好吧,現在我明白你的問題了,錯別字已經解決了,我會再試一次。

有沒有人有任何想法,爲什麼從數組內poo poos調用函數內聯?

它與關閉j有關。

在第一個例子,你解決resolvers[j][0]同步,附帶在.put()年底前++j

當你「內聯」的訪問解析器,我的意思是,用j鍵來訪問resolvers諾言的解析器,他們的下一個節拍發生異步(如++j,因此您正在訪問一個空數組索引並將其作爲函數調用。

它「無聲無息」的原因,或永遠不會解決的是,拋出的拋出只會拋出另一個「函數是未定義的」錯誤,這可能會被捕獲,除了創建的永遠不會再被引用,並且是隻是丟棄了,所以用.get()創建的諾言永遠不會解決或拒絕。