node.js中需要遍历数组并返回值的处理实在是搞不懂了...
高洛峰
高洛峰 2017-04-17 14:41:26
0
3
621
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教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

reply all(3)
Peter_Zhu

The promise changes to the resolve state before the timer is executed, and the then callback is executed and b is output.
Then the timer times out and the data is placed in b.
Resolve should be done after all timers have expired, instead of resolving directly after setting the timer.

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

This promise has no resolve or reject, so it is always pending and will not console.log. So I guess you forgot to uncomment the resolve line.

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

Inside your promise are these codes, which traverse the two-dimensional array. For each element of this two-dimensional array, set a timer that adds the element to b after 1 second. After setting the timer, the promise is resolved first. It has not yet reached 1 second, the timer has not been executed yet, and b is still an empty array. And because you resolved, the statement after your then was executed. This is the problem you encountered.
If you wait for a while (after 1 second) and then output a, it will actually be the result you want. After one second, the set timers time out and trigger, and then push elements to b.

The result you want should be written like this?

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);
})

Judge in each timer, if I am the last one in the two-dimensional array, then I will resolve. That's it.

迷茫
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]"???
阿神

I feel like the writing is very confusing. Why is there a co but not using it? The Promise is not resolved.

If you want to push an element every 1 second, you can do this.

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))
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template