“迭代"throw promises 不允许生成不同的 id [英] "Iterating" throw promises does not let to generate different ids

查看:42
本文介绍了“迭代"throw promises 不允许生成不同的 id的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读一些精彩的教程关于承诺,我发现,如果我需要交互抛出一些承诺,我不能使用 forEach 或其他一些传统"迭代机制,我必须将 Q 库用于节点,我必须迭代"使用 Q.all.

Reading some amazing tutorials about promises, I've discovered that, if I need to interate throw some promises, I can't use forEach or some other "traditional" iteration mechanisms, I have to use Q library for node, I've to "iterate" using Q.all.

我在 Nodejs Express 中编写了一个简单的示例,以确保我理解了 promise:

I've written a simple example in Nodejs Express in order to be sure I've understood promises:

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

Form.insert code simply is a promise with a console.log call, the same for Field.insert and Meta.insert

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

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

The problem is that seems to iterate right but the dynamicly generated id does not change along the promises, this is the console output:

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

对出了什么问题有任何想法吗?谢谢!!

Any ideas about what is going wrong? Thanks!!

推荐答案

它不工作的原因是因为在第一个 for 循环中,req.id 在其他 promise 开始之前设置了多次并且所有这些最终都使用最后一个随机生成的值,将您的代码更改为:

the reason it is not working is because in first for loop, the req.id is set multiple times before other promises are started and and all of them end up using the last randomly generated value, change your code to:

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 将不起作用

you would notice that I am copying all the attributes of req to clone reqCopy for I am not sure what attributes of req are required by the subsequent methods, but at the same time, single req.id would not work thanks to the async nature of code

这篇关于“迭代"throw promises 不允许生成不同的 id的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆