【问题标题】:Wait for nested JS promise to finish before resolving original promise在解决原始承诺之前等待嵌套的 JS 承诺完成
【发布时间】:2019-05-29 08:17:05
【问题描述】:

我是 Promises 的新手,在解决原始 Promise 之前等待嵌套的 Promise 完成所有执行的概念有点麻烦。

原始代码

function getSomething(text) {
    return new Promise(function (resolve, reject) {
        getElse(text).then(function (items) {
            if (items.length !== 0) {

                /* Stuff here */

                getElseElse(box).then(function (moreItems) {

                    /* Stuff here */

                    return array;
                }.then(function (array) {
                    var promise = new Promise(function (resolve, reject) {
                        /* anotherFunction() is asynchronous */
                        result = anotherFunction(array); <-- Spot 1
                    });
                    promise.then(function () { });
                });

                return resolve(result); <--- Spot 2

            }
            else {
                return resolve(null);
            }
        });
    });
};

更新的代码 - 更好,但仍不能完全按照我的意愿工作。

function getSomething(text) {
    return getElse(text).then(function (items) {
        if (items.length !== 0) {

            /* Stuff here */

            return getElseElse(box).then(function (moreItems) {

                /* Stuff here */

                return array;
            }).then(anotherFunction);

        } else {
            return null;
        }
    });
}

然后,在单个视图页面中,我有这个:

getSomething(text).then(function (result) {
    /* Do something here using result */
    /* But result is undefined and I think still pending */
});

我已经在 Thomas 的帮助下优化了原始函数,但视图内的原始调用似乎在result 制定之前仍在继续。

我希望 getSomething() 完全完成并返回 result,然后再执行视图内的 .then 内的代码。到目前为止,这还没有实现。

我发现了几篇文章指出了我认为Promise.all 的正确方向,但我似乎无法真正了解这些信息,所以我希望有人可以帮助解释我的具体情况情况。

有帮助的帖子是:

  1. Promise Chain not waiting for promises to resolve before ending
  2. Wait until nested promises resolve
  3. Wait for promises inside Promise.all to finish before resolving it

解决方案

Thomas 在标记的答案中解决了原始问题。经过进一步检查,最终问题在anotherFunction() 内部解决。

原来:

function anotherFunction(array) {
    return new Promise(function (resolve, reject) {
        return anotherGet(parcels).then(function (list) {
            /* Do stuff here without a return */
        });
    });
}

固定版本:

function anotherFunction(array) {
    return anotherGet(parcels).then(function (list) {
        /* Do stuff here */
        return list;
    });
}

【问题讨论】:

  • 我认为您首先不需要将其包装在 Promise 中;你已经收到了来自getElse() 的承诺;只是返回。同样,.then() 处理程序可以返回 getElseBox() Promise。
  • 问题中不清楚:anotherFunction()是异步的吗?
  • @MarkMeyer 我很抱歉,但确实如此。我会将其添加到帖子中。
  • 更新了问题,希望能更好地表达问题。

标签: javascript promise nested


【解决方案1】:

首先,避免使用 Promise/Deferred 反模式。很少你需要创建自己的 Promise,通常你有一些返回 Promise 的函数;使用它。

其次,为了让外部 Promise 等待一个嵌套的 Promise,您需要将该嵌套的 Promise 返回到外部 Promise。
在 then() 内部返回一个 Promise 将使生成的 Promise 解析为您在内部重新调整的 Promise 的值。

最后,.then(value =&gt; value) 或 .then(value =&gt; Promise.resolve(someFunction(value))) 之类的东西毫无意义。您对anotherFunction 的包装器基本上只是传递了参数并返回了结果。

因此,您的伪代码应如下所示:

function getSomething(text) {
  return getElse(text).then(function (items) {
    if (items.length !== 0) {
      /* Stuff here */
      return getElseElse(box).then(function (moreItems) {
        /* Stuff here */
        return array;
      }).then(anotherFunction);
    } else {
      return null;
    }
  });
}

【讨论】:

  • 我想从整个事情中返回的是result,而不是array。我传入 array 并返回 result 的原因是因为 array 是一个查找数组,而 result 是一个类从具有更多信息的查找中生成。我需要将 array 传递给 anotherFunction() 以便我可以从该函数返回结果,并且我需要等到之前的项目完成后再执行 anotherFunction() 使用 array。这就是我做那部分的原因(可能仍然是错误的哈哈)。我怎样才能使用你的 sudo 之类的东西返回我想要的东西?
  • @Hank,就你的 sn-p 而言,result = anotherFunction(array)。这正是 .then(anotherFunction); 在我的代码中所做的。
  • 好的,那么事情就解决了。我不知道语法以这种方式工作。我会试一试,让你知道它是否像我想要的那样工作,我相信它会的。我有一种强烈的感觉,我的代码主要是效率低下,哈哈
  • 我更新了帖子,提供了更多信息,希望对您有所帮助。您的建议似乎更接近我想要的结果,但 getSomething().then() 似乎没有正确等待结果。
  • 找出最后的问题并更新帖子并标记您的答案。感谢您的帮助
【解决方案2】:

基本技巧是确保您的所有 resolve() 调用都在嵌套的 Promise 的 then() 方法内。

类似的东西:

function getSomething(text) {
    return new Promise(function (resolve, reject) {
        getElse(text).then(function (items) {
            if (items.length !== 0) {

                /* Stuff here */

                getElseElse(box).then(function (moreItems) {

                    /* Stuff here */

                    return array;
                }.then(function (array) {
                    var promise = new Promise(function (resolve, reject) {
                        result = anotherFunction(array); <-- Spot 1
                    });
                    promise.then(function () { });

                    resolve(result); <--- Spot 2
                });    
            }
            else {
                resolve(null);
            }
        });
    });
};

如果它需要嵌套在上面的promise.then() 中,只需将其粘贴在那里即可。

另请注意,您不需要返回您的解决方案。打电话给他们。

【讨论】:

    猜你喜欢
    • 2017-04-02
    • 2017-04-04
    • 2015-07-18
    • 2019-04-29
    • 1970-01-01
    • 2018-03-19
    • 2018-12-14
    • 2015-06-24
    • 2018-04-02
    相关资源
    最近更新 更多