搜尋

首頁  >  問答  >  主體

node.js中需要遍历数组并返回值的处理实在是搞不懂了...

var a = [[1,2,3],[4,5,6],[7,8,9]]
var b = []

const co = require('co');

new Promise(function(resolve, reject) {
  a.forEach(function(item) {
    item.forEach(function(it) {
      setTimeout(function () {
        b.push(it)
      }, 1000);
    })
  })
 // resolve(b)
}).then(function(data){
  console.log(data);
})

// 主要是异步的问题还是怎么的,会直接返回b = [] 而不是期待的
// b = [1,2,3,4,5,6,7,8,9]
高洛峰高洛峰2871 天前655

全部回覆(3)我來回復

  • 天蓬老师

    天蓬老师2017-04-17 14:43:26

    promise在定時器執行之前,變成了resolve狀態,執行了then的回調輸出了b。
    然後定時器才會超時,將資料放到b裡。
    應該在定時器全部超時之後在resolve,而不是僅僅在設定完定時器之後直接resolve。

    new Promise(function(resolve, reject) {
      // code
      // resolve(b)
    }).then(function(data){
      console.log(data);
    })

    這個promise沒有resolve,也沒有reject,所以一直是pending,不會console.log。所以我猜測,你應該是忘記去掉resolve這行的註解了。

      a.forEach(function(item) {
        item.forEach(function(it) {
          setTimeout(function () {
            b.push(it)
          }, 1000);
        })
      })
      resolve(b)

    你的promise裡面是這些程式碼,二維陣列的遍歷。對於這個二維數組的每個元素,設定定時器,這個定時器在1秒後將元素加到b裡。設定好定時器後,promise先resolve了,這時候還沒到1秒,定時器還沒執行,b還是空數組。而由於你resolve了,所以執行了你then後的語句,這時候就是你遇到的問題了。
    如果你等一會(1秒後)再輸出a,其實是你想要的結果的。一秒後,設定的這些定時器超時觸發,再向b裡push元素。

    你想要的結果該這麼寫呢?

    var a = [[1,2,3],[4,5,6],[7,8,9]]
    var b = []
    
    new Promise(function(resolve, reject) {
      a.forEach(function(item) {
        item.forEach(function(it) {
          setTimeout(function (item, it) {
            b.push(it)
              if(item == a[a.length-1] && it == item[item.length -1]) {
              resolve(b);
            }
          }, 1000, item, it);
        })
      })
    }).then(function(data){
      console.log(data);
    })

    在每個定時器裡判斷,如果我是二維數組裡的最後一個,那麼我就resolve。這樣就可以了。

    回覆
    0
  • 迷茫

    迷茫2017-04-17 14:43:26

    雷雷

    回覆
    0
  • 阿神

    阿神2017-04-17 14:43:26

    感覺寫的很混亂啊,怎麼又有co,又不用,Promise也沒resolve。

    如果是想每1秒push一個元素,可以這樣。

    const a = [[1,2,3],[4,5,6],[7,8,9]]
    const b = []
    
    const promise = (n) => new Promise((resolve, reject) => {
      const timer = setTimeout(() => {
        console.log('pushing ', n)
        b.push(n)
        window.clearTimeout(timer)
        resolve()
      }, 1000)
    })
    
    const c = a.reduce((prev, cur) => prev.concat(cur))
    
    const main = () => {
      console.log('start')
      return c.reduce((prev, cur) => {
        return prev.then(() => promise(cur))
      }, Promise.resolve())
    }
    
    main().then(() => console.log(b))

    回覆
    0
  • 取消回覆