【问题标题】:JSON array undefined & empty in promise BluebirdJSON 数组未定义且在 Promise Bluebird 中为空
【发布时间】:2016-12-21 04:24:06
【问题描述】:

我正在使用 Promise bluebird 处理文件中的 json 数组对象。如果我想将数据存储在 json 数组(称为列表)中并在最终过程中返回,则会出现问题。 在列表返回后甚至在最终过程中,列表为空/未定义。运行代码,我总是有 1 个不为 false 的值触发列表中 json 的添加/推送。

你能帮我解决这个问题吗?您将在下面找到我的代码。

提前致谢!!!

var Promise = require('bluebird');
var join = Promise.join;
var fs = Promise.promisifyAll(require("fs"));

fs.readdirAsync(dir).map(function (filename) {
    return fs.readFileAsync(dir + "/" + filename, "utf8");
}).then(function(result){
    var list=[];

    result.map(function(row, index){
      Promise.coroutine(function*() {
        update(row, index).then(function(value){
          if (value!=false){
            var trade_update = new updated_Item(row.ID, row.Quantity, row.Price, row.Remark);
            list.push(trade_update);
            console.log(JSON.stringify(list));          <-- This works. It gives me data
          }
          return list;
        })
      })();
    });
    console.log('list: ' + JSON.stringify(list));        <-- output:    list:[]
    return list;
}).finally(function(result){
  console.log('Final outcome: '+ ' ' + JSON.stringify(result));      <-- output: Final outcome: undefined
})

在 Samuel 的帮助下,我的代码现在是:

var Promise = require('bluebird');
var join = Promise.join;
var fs = Promise.promisifyAll(require("fs"));


function updateOrder(done){
  fs.readdirAsync(dir).map(function (filename) {
      return fs.readFileAsync(dir + "/" + filename, "utf8");
  }).then(function(result){
    var list=[];

    result.map(function(row, index){
      Promise.coroutine(function*() {
        update(row, index).then(function(value){
          if (value!=false){
            var trade_update = new updated_Item(row.ID, row.Quantity, row.Price, row.Remark);
            list.push(trade_update);
            done(list);      
          }
        })
      })();
    });

    //done(list);   <--if I put the done callback here, it will give me an empty list. I though once the result.map finished processing all the values give me the end result.
  }
}

updateOrder(function(resultList){
  console.log('List' + JSON.stringify(resultList));
})

现在每次更新(推送)列表时,这段代码都会给我整个结果列表。

一旦函数 updateOrder 完成,我会在最后收到 resultList。

【问题讨论】:

  • Promise.coroutine 是异步的,所以list 直到稍后才会得到任何值。

标签: json node.js promise bluebird


【解决方案1】:

如评论中所述。 Promise.coroutine 是异步的,因此这意味着在您的代码到达结果后不会立即返回结果。这几乎解释了您在代码中看到的后一个打印语句表明list 未定义的现象。

您可以做的是将获得的整个代码包装在一个函数中,然后添加一个callback 函数作为async 函数的参数,以便在它完成任务时调用,同时返回填充的列表供以后处理。

我已经为您的案例编写了一个伪代码,很遗憾我无法在我的 IDE 上对其进行测试,但这个概念已经存在并且应该可以工作。

考虑一下我的伪代码:

var Promise = require('bluebird');
var join = Promise.join;
var fs = Promise.promisifyAll(require("fs"));

// Wrap everything you got into a function with a `done` parameter (callback fn)
function doStuff(done) {
  fs.readdirAsync(dir).map(function (filename) {
    return fs.readFileAsync(dir + "/" + filename, "utf8");
  }).then(function(result){
    var list=[];

    result.map(function(row, index){
      Promise.coroutine(function*() {
        update(row, index).then(function(value){
          if (value!=false){
            var trade_update = new updated_Item(row.ID, row.Quantity, row.Price, row.Remark);
            list.push(trade_update);
          }
          done(list);
        })
      })();
    });
  }).finally(function(result){
    console.log('File read finish, but this doesnt mean I have finished doing everything!');
  })
}

// call your function and provide a callback function for the async method to call 
doStuff(function(resultList) {
  console.log('list: ' + JSON.stringify(resultList));
  // Continue processing the list data.
});

【讨论】:

  • @BigSkinny 让我知道这个解决方案是否对您有意义,很高兴进一步讨论
  • 嗨 Samuel Toh,它有效。我现在得到名单。我已经完成了(列表);在 if 函数内部并删除了 finally 函数,因为它没有附加值。太好了,谢谢你的帮助!!!
  • 现在 done 参数将在每次运行 result.map 时被调用。我尝试更改它,只是通过将 done(list) 移动到代码中的另一个位置来调用 done 参数,但如果我移动它,结果列表是空的。知道这是为什么吗?
  • 我的意思是,只有在 doStuff 函数中完成所有操作后才能收到 resultList
  • @BigSkinny 为了让我更容易诊断您的问题,您想用更新的源代码提出另一个问题吗?如果不查看任何代码,我可能很难弄清楚您当前的状态。如果您确实提出另一个问题,请给我一个 ping。谢谢
猜你喜欢
  • 2021-11-09
  • 2016-03-20
  • 1970-01-01
  • 2021-10-28
  • 2016-06-16
  • 1970-01-01
  • 2014-05-06
  • 1970-01-01
  • 2023-03-31
相关资源
最近更新 更多