Domanda

I am using the promise library bluebird with node 0.11.9 running with the flag --harmony

I have a simple working example:

var Promise = require('bluebird');
var fs = require('fs');
var readdirAsync = Promise.promisify(fs.readdir, fs);
var statAsync = Promise.promisify(fs.stat, fs);

Promise.spawn(function *() {
  var files = yield readdirAsync('./');
  var stats = yield files.map(function(file) { return statAsync(file); });
  console.log(stats);
  console.log('done');
});

This works fine and output the list of nodes' stats. But with the following version: there is no output at all:

var Promise = require('bluebird');
var fs = require('fs');
var readdirAsync = Promise.promisify(fs.readdir, fs);
var statAsync = Promise.promisify(fs.stat, fs);

Promise.spawn(function *() {
  var files = yield readdirAsync('./');
  var stats = yield files.map(statAsync);
  console.log(stats);
  console.log('done');
});

Any idea of why this doesn't work ?

È stato utile?

Soluzione

The problem is unfortunately that Promise.promisify isn't perfect. It doesn't know how many arguments fs.stat should have. It passes through whatever arguments you give it, as well as the node style callback.

Array.prototype.map doesn't call the mapping function with a single argument. Instead it gives it the item, the index in the array, and a copy of the array. Therefore your second example looks like:

var Promise = require('bluebird');
var fs = require('fs');
var readdirAsync = Promise.promisify(fs.readdir, fs);
var statAsync = Promise.promisify(fs.stat, fs);

Promise.spawn(function *() {
  var files = yield readdirAsync('./');
  var stats = yield files.map(function(file, i, a) { return statAsync(file, i, a); });
  console.log(stats);
  console.log('done');
});

If the callback doesn't appear until the fourth argument, fs.stat will never call it.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top