当前位置: 首页 > 知识库问答 >
问题:

嵌套为循环转换为嵌套promise

敖永丰
2023-03-14

我遇到了一个问题,我的程序只在nameList的一次迭代中结束,我不确定不合逻辑的代码在哪里。

全球给予:

var _ = require("underscore");
var nameList = ["Bob", "Susie"]
var jsonDict = {}

我复杂的嵌套从这里开始,但我不确定如何修复它,以便它迭代通过nameList和数字for-循环1-10

return new Promise((res, rej) => {
    var promises = [];
    return Promise.map(nameList, function(personName){
        for (var j=1; j<=10; j++){
            return promises.push(new Promise(function(resolve, reject) {
                params['page'] = j;

                console.log('PAGE ' + j + ' ' + personName)

                SOME_SEARCH_FX_THAT_RETURNS_A_PROMISE(params).then(function(data){
                    return Promise.map(data, function(item, index){
                        if (!_.has(jsonDict, item.key)){
                            jsonDict[item.key] = {
                                name: personName
                            }
                        }
                        return
                    }).then(function(){
                        console.log(jsonDict)
                        return resolve(true)
                    })

                }).catch(function(err){
                    console.log(err)
                    return reject(false)
                })
            }))
        }
    }).then(function(){
        return res(true)
    })
}).then(function(){
    console.log('Done with everything.')
})

我得到以下输出:

PAGE 1 Bob
PAGE 1 Susie
Done with everything.

{ 
    '12345': { name: "Bob" },
    '12346': { name: "Bob" },
    ...
    '99999': { name: "Bob" }
}

我从来没有得到Susie的数据,我很早就回来了,但似乎不知道在哪里。对于问题所在(甚至重构)的任何帮助/指导都将不胜感激。提前谢谢!

共有1个答案

习阳
2023-03-14

我之所以说根本缺陷是因为您似乎误解了函数的工作原理

return Promise.map(nameList, function(personName){  <-- this function 
  for (var j=1; j<=10; j++){
    return promises.push(new Promise(function(resolve, reject) { <-- is returning HERE

在这里,rray.prototype.push函数返回新添加项的索引。(我查了一下,直到)
这里最大的问题是你正在归还它。

只要您返回Promise.map的映射器函数,您就告诉它您的操作完成了!因此,在上面的代码中,它甚至无法进入循环的下一次迭代

在MDN中查找返回的规范

返回语句结束函数执行,并指定要返回给函数调用方的值。

希望这能回答你的问题,让你提前回到哪里。

我也很难信守诺言。让我给你们介绍一篇关于我最近读到的promise的精彩文章。现在让我应用我从中学到的东西。谢谢你的提问。

我们promise要与地狱搏斗,但你却违背了我们的promise。

我会试着从最嵌套的部分开始平滑promise

SOME_SEARCH_FX_THAT_RETURNS_A_PROMISE(params).then(function(data){
    return Promise.map(data, function(item, index){
        if (!_.has(jsonDict, item.key)){
            jsonDict[item.key] = {
                name: personName
            }
        }
        return
    }).then(function(){
        console.log(jsonDict)
        return resolve(true)
    })

}).catch(function(err){
    console.log(err)
    return reject(false)
})

这里的内部promise映射是不必要的,您可以使用标准的映射,甚至是for循环,因为您实际上没有在这里映射任何东西。。。

// Create subroutine, careful with the globals...
let populateJsonDict = singleData => {
  if (!_.has(jsonDict, singleData.key)) jsonDict[singleData.key] = { name: personName }
}

SOME_SEARCH_FX_THAT_RETURNS_A_PROMISE(params).then(data => {
    data.forEach(populateJsonDict);
    resolve(true); // this will be removed later
}).catch(function(err){
    console.log(err);
    reject(false); // this will be removed later
})

好的,让我们向上移动回调金字塔(或者向下移动?)。下一个

for (var j=1; j<=10; j++){
  return promises.push(new Promise(function(resolve, reject) {
    params['page'] = j;

    console.log('PAGE ' + j + ' ' + personName)

    //[Refactored 1]
  }))
}

又是一个不必要的promise,是时候摆脱它了。这里的问题的基石,返回

for (var j=1; j<=10; j++){
  //[from Refactored 1]
  let populateJsonDict = singleData => {
    if (!_.has(jsonDict, singleData.key)) jsonDict[singleData.key] = { name: personName }
  }
  params['page'] = j; // I assume this a global somewhere
  let p = SOME_SEARCH_FX_THAT_RETURNS_A_PROMISE(params).then(data => {
    data.forEach(populateJsonDict);
    // Removed because we've removed the parent promise
  }).catch(function(err){
    console.log(err);
    // Removed because we've removed the parent promise
  })
  promises.push(p)
}

我会快进,因为我注意到这变得非常长。下一块要重构

return new Promise((res, rej) => {
    var promises = [];
    return Promise.map(nameList, function(personName){
      //[Refactored 2]
    }).then(function(){
      return res(true)
    })
}).then(function(){
    console.log('Done with everything.')
})

我真的不知道如何挽救这一切,所以我会从小组里写一些东西。

var promises = [];
nameList.forEach(personName => { // Like earlier, redundant Promise.map
  //[from Refactored 2]
  for (var j=1; j<=10; j++){
    let populateJsonDict = singleData => {
        if (!_.has(jsonDict, singleData.key)) jsonDict[singleData.key] = { name: personName }
    }
    params['page'] = j;
    let p = SOME_SEARCH_FX_THAT_RETURNS_A_PROMISE(params).then(data => {
        data.forEach(populateJsonDict);
    }).catch(function(err){
        console.log(err);
    })
    promises.push(p)
  }
});
// At this point you have an array of Promises, for this we can utilize Promise.all

Promise.all(promises)
    .then(() => console.log('Done with Everything'));

我想这本可以做得更好。让我做最后一个版本。

let populateJsonDict = name => key => !_.has(jsonDict, key) && Object.assign(jsonDict, {[key]:name};
let promises = _.times(10, 
    index => {
        params['page'] = index+1;
        return Promise.map(nameList, name => {
            let populateWithName = populateJsonDict(name);
            let iterate = data => data.forEach(populateWithName);
            return SOME_SEARCH_FX_THAT_RETURNS_A_PROMISE(params)
                .then(iterate)
                .catch(err => console.log(err));
        });
    });

Promise.all(promises)
    .then(() => console.log('Everything done'));

好吧,仍然有这种不满意的感觉,但这就是我现在所拥有的。。。这对我来说比你更重要。再次感谢你,朋友。我希望我们双方都能继续推进这一不断变化的工作领域。如果所有这些听起来都是居高临下的话,我道歉。干杯

 类似资料:
  • 用python编写了这个函数,可以转换矩阵: 在这个过程中,我意识到我并不完全理解单行嵌套for循环是如何执行的。请回答以下问题,帮助我理解: 这个for循环的执行顺序是什么 鉴于 对象必须是什么类型才能将其用于循环结构? i和j分配给对象元素的顺序是什么? 可以用不同的for循环结构来模拟吗? 这个for循环可以嵌套在一个类似或不同的for循环结构中吗?它看起来怎么样? 如需更多信息,我们也将不

  • Python 不仅支持 if 语句相互嵌套,while 和 for 循环结构也支持嵌套。所谓嵌套(Nest),就是一条语句里面还有另一条语句,例如 for 里面还有 for,while 里面还有 while,甚至 while 中有 for 或者 for 中有 while 也都是允许的。 当 2 个(甚至多个)循环结构相互嵌套时,位于外层的循环结构常简称为 外层循环或 外循环,位于内层的循环结构常简

  • 这是我的代码。我遇到的问题是,我希望将HP在我的PHP代码中的数字转换为我的HP HTML代码,以及与Cylinder相同的内容。我已经想好了其他的东西,但说到这一部分我就卡住了

  • 本文向大家介绍MATLAB嵌套循环,包括了MATLAB嵌套循环的使用技巧和注意事项,需要的朋友参考一下 示例 可以嵌套循环,以在另一个迭代任务中执行迭代任务。考虑以下循环: 我们使用2个迭代器来显示abc和中元素的所有组合1:m,从而得出: 我们还可以使用嵌套循环来组合每次要完成的任务和几次迭代中要完成的任务: 这里我们要计算所有的斐波那契数列,但是n每次只显示第一个元素,所以我们得到 我们可以做

  • 嵌套循环就是在一个循环中还有一个循环,内部循环在外部循环体中.在外部循环的每次执行过程中都会触发内部循环,直到内部循环执行结束.外部循环执行了多少次,内部循环就完成多少次.当然,不论是外部循环或内部循环的break语句都会打断处理过程. 例子 10-19. 嵌套循环 1 #!/bin/bash 2 # nested-loop.sh: 嵌套的"for" 循环. 3 4 out

  • 3.4.4 嵌套循环 为了实现复杂的算法,控制结构可以相互嵌套,即一个控制结构处于另一个控制结构的 内部。前面我们见过 if 结构的嵌套,现在我们讨论循环的嵌套。 先考虑“一维”数据结构——由简单数据值构成的列表,为了遍历列表以处理其中数据, 我们需要一个循环。例如用一个循环来计算列表中所有数据之和: >>> a = [1,2,3,4,5] >>> sum = 0 >>> for i in a: