node.js中需要遍历数组并返回值的处理实在是搞不懂了...
高洛峰
高洛峰 2017-04-17 14:41:26
0
3
614
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]
高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

membalas semua(3)
Peter_Zhu

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。这样就可以了。

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

new Promise(function(resolve, reject) {

  for (var i = 0; i < a.length; i++) {
    for (var j = 0; j < a[i].length; j++) {
      b.push(a[i][j])
      console.log(a[i][j]);
      if(i+1 === a.length && j+1 === a[i].length) resolve()
    }
  }
}).then(console.log(b));


// "b = [1,2,3,4,5,6,7,8,9]"???
阿神

感觉写的很混乱啊,怎么又有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))
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan