"迭代" throw promise不会让生成不同的id

时间:2016-05-25 09:26:02

标签: javascript node.js promise q

阅读关于承诺的some amazing tutorials,我发现,如果我需要互相投入一些承诺,我就无法使用每个或其他传统的#34;迭代机制,我必须使用Q库作为节点,我必须"迭代"使用Q.all

我在Nodejs Express中写了一个简单的例子,以确保我理解了承诺:

var form = [
    {'name':'FORM_NAME_1.1',
     'label2':'FORM_LABEL_1.2'
    },
    {'name':'FORM_NAME_2.1',
     'label2':'FORM_LABEL_2.2'
    }
];
var params = ['params1','params2'];
var meta   = ['meta1','meta2'];

app.get('/', (req,res) => {
        return Q.all([
            form.map((currentValue,index,arr) => {
                req.id = Math.random();   //Random ID to be used in the next promises
                console.log(currentValue);
                return Form.insert(currentValue,req);
            }),
            params.map((currentValue,index,arr) => {
                console.log(req.id);
                return Field.insert(currentValue,req.id);
            }),
            meta.map((currentValue,index,arr) => {
                console.log(req.id);
                return Meta.insert(currentValue,req.id);
            })
        ])
    .catch((err) => next(err))
    .done(() => console.log('It\'s done'));
});

Form.insert代码只是一个console.log来电的承诺,同样适用于Field.insertMeta.insert

var Form = {
    insert: (param1,req) => {
        var deferred = Q.defer();
        console.log('Goes throw Form');
        deferred.resolve();
        return deferred.promise;
    }
}

问题是似乎迭代正确但动态生成的id不会改变沿着承诺,这是控制台输出:

Listening at port 3000...
{ name: 'FORM_NAME_1.1', label2: 'FORM_LABEL_1.2' }
Goes throw Form
{ name: 'FORM_NAME_2.1', label2: 'FORM_LABEL_2.2' }
Goes throw Form
0.3757301066790548
Goes throw Field
0.3757301066790548
Goes throw Field
0.3757301066790548
Goes throw Meta
0.3757301066790548
Goes throw Meta
It's done

关于出了什么问题的任何想法?谢谢!

1 个答案:

答案 0 :(得分:1)

它不起作用的原因是因为在第一个for循环中,req.id在其他promises启动之前被设置了多次,并且所有这些都使用最后一个随机生成的值结束,将代码更改为:

app.get('/', (req,res) => {

  let process = (currentValue,index,arr) => {
    let reqCopy = {id: Math.random()}
    for(let attr in req)   // copy all the request attributes
      if(attr && attr!='id')
        reqCopy[attr] = req[attr]
    return Q.all([
      Form.insert(form[index],reqCopy),
      Field.insert(params[index],reqCopy),
      Meta.insert(meta[index],reqCopy)
      ])
  }
  return Q.all(form.map(process))
    .catch(next)
    .done(() => console.log('It\'s done'));
})

您会注意到我正在将req的所有属性复制到克隆reqCopy,因为我不确定后续方法需要req的哪些属性,但同时时间,由于代码的异步特性,单req.id将无效。