【问题标题】:Promise.map function .then() block getting null before nested promise resolvesPromise.map 函数 .then() 在嵌套的 Promise 解决之前阻止获取 null
【发布时间】:2017-09-11 04:32:43
【问题描述】:

我正在启动一个嵌套的 Promise 映射,并看到外部 .then() 块在调用函数中的 resolve 之前打印一个空结果。

我觉得我一定是弄乱了语法。我做了这个精简的例子:

const Promise = require('bluebird');
const topArray = [{outerVal1: 1,innerArray: [{innerVal1: 1,innerVal2: 2}, {innerVal1: 3,innerVal2: 4}]},{outerVal2: 2,innerArray: [{innerVal1: 5, innerVal2: 6 },  {innerVal1: 7,innerVal2: 8 }]}] ;

promiseWithoutDelay = function (innerObject) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log("promiseWithDelay" ,innerObject);
            let returnVal = {}
            returnVal.innerVal1 = innerObject.innerVal1;
            returnVal.innerVal2 = innerObject.innerVal2;
            returnVal.delay = false;

            return resolve(returnVal);
        }, 0);
    })
}
promiseWithDelay = function (innerObject) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log("promiseWithDelay" ,innerObject);
            let returnVal = {}

            returnVal.innerVal1 = innerObject.innerVal1;
            returnVal.innerVal2 = innerObject.innerVal2;
            returnVal.delay = true;
            return resolve(returnVal);
        }, 3000);
    })
}

test1 = function () {
    let newArray = [];
    let newArrayIndex = 0;

    Promise.map(topArray, function (outerObject) {

        Promise.map(outerObject.innerArray, function (innerObject) {

            Promise.all([
                promiseWithoutDelay(innerObject),
                promiseWithDelay(innerObject)
            ])
                .then(function (promiseResults) {
                    newArray[newArrayIndex++] = {result1: promiseResults[1], result2: promiseResults[2]}

                })
        })
    })
        .then(function () {
            return newArray;
        })
}

var result = test1();

console.log("got result ",result);

我想要做的是循环一个外部数组,该数组具有我需要的一些值。
这些值包括一个嵌套的内部数组,我还必须循环该数组以获取一些值。
在内部循环中,我将外部和内部值传递给 Promise.all 中的 promise 函数。
当 promise 函数解析时,它们被分配给一个返回对象。
它似乎工作正常,除了其中一个 promise 函数有时会在进行一些计算时出现延迟。
发生这种情况时,它会被排除在返回值之外,因为它尚未解决。

难道不应该等到带有 Promise.all 的内循环解决后再从外循环返回吗?

你能指出我正确的方向吗?

编辑:根据@Thomas 的建议结束了这个解决方案:

test1 = function(){
    return Promise.map(topArray, function(outerObject){
        let oVal = outerObject.outerVal;
        return Promise.map(outerObject.innerArray, function(innerObject){
            innerObject.oVal = oVal;
            return Promise.all([ promiseWithDelay(innerObject), promiseWithoutDelay(innerObject)])
                .then(function(results) {
                    return { result1: results[0], result2: results[1], delay: results[2] } ;
                })
        })
    }).reduce(function(newArray, arr){
        return newArray.concat(arr);
    }, []);
}

【问题讨论】:

  • 不要使用new Promise() 来编写promise。而是直接返回Promise.all() 调用。
  • Shouldn't it wait until the inner loop with Promise.all resolves before it returns from the outer loop? 不,因为您不返回此承诺,因此外部循环评估/等待的值是隐式返回的 undefined 值。由于这不是承诺,因此无需等待。
  • @Thomas 当我执行 console.log("returning inner newArray: ", newArray );返回解析(新数组); ?
  • @SLaks 感谢您指出这一点
  • @GForce,抱歉没有看到。但这使情况变得更糟。一旦第一次迭代完成,你就解决了你的外部 Promise。它基本上是for(var value of array){ /*...*/ return something } 的异步版本,您想知道循环没有完成。看看我的回答

标签: javascript arrays node.js promise bluebird


【解决方案1】:

我不完全确定我是否从您的精简示例中得到了您的问题,但我认为您想要在这里做的是:

test1 = function(){
    return Promise.map(topArray, function(outerObject){
        return Promise.all(outerObject.innerArray)
    }).reduce(function(newArray, arr){
        return newArray.concat(arr);
    }, []);
}

【讨论】:

  • 哇,真干净。谢谢
  • 不过,这只是将数组传入以减少并将它们连接在一起。我需要调用 promiseWithDelay 和 promiseWithoutDelay 函数,传入一些值。现在搞砸了:)
  • 编辑了我的问题以包括我最终得到的内容。看起来比我一开始的烂摊子好多了:)
猜你喜欢
  • 1970-01-01
  • 2020-12-27
  • 1970-01-01
  • 2019-02-27
  • 1970-01-01
  • 2017-04-02
  • 2019-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多