当前位置: 首页 > 面试题库 >

用另一个承诺来履行(不解决)承诺

洪和风
2023-03-14
问题内容

我要兑现一个承诺。关键是我真的想在第一个诺言兑现后立即访问(仍在等待中的)第二个 诺言
。不幸的是,当两个诺言都实现时,我似乎只能获得第二个诺言的解决值。

这是我想到的用例:

var picker = pickFile();

picker.then(  // Wait for the user to pick a file.
    function(downloadProgress) {
        // The user picked a file. The file may not be available just yet (e.g.,
        // if it has to be downloaded over the network) but we can already ask
        // the user some more questions while the file is being obtained in the
        // background.

        ...do some more user interaction...

        return downloadProgress;
    }
).then( // Wait for the download (if any) to complete.
    function(file) {
        // Do something with the file.
    }
)

该功能pickFile显示文件选择器,用户可以在其中从自己的硬盘驱动器或URL中选择文件。它返回一个承诺picker,该承诺将在用户选择文件后立即兑现。此时,我们可能仍然必须通过网络下载所选文件。因此,我不能picker将所选文件作为分辨率值。相反,picker应该通过另一个promise来实现,该promise
downloadProgress最终将通过所选文件来实现。

对于完整性,这是该pickFile函数的模拟实现:

function pickFile() {
    ...display the file picker...

    var resolveP1 = null;

    var p1 = new Promise(
        function(resolve, reject) {
            resolveP1 = resolve;
        }
    );

    // Mock code to pretend the user picked a file
    window.setTimeout(function() {
        var p2 = Promise.resolve('thefile');
        resolveP1(p2);  // <--- PROBLEM: I actually want to *fulfill* p1 with p2
    }, 3000);

    return p1;
}

在标线的问题是,我想 履行 承诺p1新的承诺p2,但我只知道如何 解决 它。满足与解决之间的区别在于,解决首先检查所提供的值p2是否再次是一个承诺。如果是,则将p1延迟实现,直到实现为止p2,然后p1将使用p2的解析度值而非p2自身来实现。

我可以通过围绕构建包装器来解决此问题p2,即替换行

        resolveP1(p2);  // <--- PROBLEM: I actually want to *fulfill* p1 with p2

从第二个代码示例

        resolveP1({promise: p2});

然后,在第一个代码示例中,我将不得不替换该行

        return downloadProgress;

通过

        return downloadProgress.promise;

但是,当我真正想做的只是兑现(而不是解决)承诺时,这似乎有点不合时宜。

我将不胜感激任何建议。


问题答案:

除了我已经在问题中描述的解决方法之外,似乎没有其他解决方案。供将来参考,如果您想实现(而不是解决)p带有value
的诺言val,其中val另一个诺言,那么仅p通过参数调用诺言解析函数val将无法正常工作。它将导致p“锁定”在的状态val,以便一旦满足,p将使用val的分辨率值val来满足(请参见spec)。

相反,请包装val另一个对象并p对该对象进行解析:

var resolveP;  // Promise resolution function for p

var p = new Promise(
    function(resolve, reject) {
        resolveP = resolve;
    }
);

function fulfillPwithPromise(val) {  // Fulfills p with a promise val
    resolveP({promise: val});
}

p.then(function(res) {
    // Do something as soon as p is fulfilled...

    return res.promise;
}).then(function(res) {
    // Do something as soon as the second promise is fulfilled...
});

如果您已经知道这val是一个承诺,那么此解决方案就可以使用。如果您不能对val的类型做任何假设,那么您似乎很不走运。您必须 始终
将承诺解决方案值包装在另一个对象中,或者可以尝试检测是否val具有then类型为“功能” 的字段并有条件地包装它。

也就是说,在某些情况下,承诺解决方案的默认行为实际上可能会产生预期的效果。因此,仅在您确定要 实现 而不是用第二个承诺 解决
第一个承诺时,才使用上述解决方法。



 类似资料:
  • 问题内容: 我对诺言不太熟悉。我想从承诺电话中隐藏承诺的实现。 例: 然后我将在同一文件中而不是在同一函数中解决我的诺言,我称其为诺言。 现在,我知道“ promiseFriend”是不确定的。我如何才能将承诺电话与承诺解决方案区分开? 问题答案: 如果要在函数中定义一个promise并在其他地方使用它,则首先需要从该函数返回promise,而您在代码中没有这样做。然后,您需要实际调用您也没有执行

  • 问题内容: 考虑以下以串行/顺序方式读取文件数组的代码。返回一个promise,仅当依次读取所有文件后,promise才会解析。 上面的代码有效,但是我不喜欢必须递归使事情顺序发生。有没有更简单的方法可以重写此代码,这样我就不必使用怪异的函数了? 最初我尝试使用,但是这导致所有调用同时发生,这 不是 我想要的: 问题答案: 2017年更新 :如果环境支持,我将使用异步功能: 如果需要,可以使用异步

  • 问题内容: 无论我的Promise是否成功解决,我都想执行相同的操作。我不想将相同的功能绑定到两个参数。没有像jQuery一样的东西吗?如果没有,我该如何实现? 问题答案: 没有像jQuery一样的东西吗? 如果没有,我该如何实现? 您可以这样实现自己的方法: 或更广泛地讲,将解析信息传递给回调: 两者都确保原始解析得以维持(当回调中没有异常时),并确保等待诺言。

  • 问题内容: 我有一个整数id的数组,例如 并且我需要为每个ID执行异步远程调用。每个调用都是一个使用$ resource执行的WebAPI请求,并显示为Promise。 我需要创建一个接受这些ID数组的函数,然后初始化递归承诺链。该链应导致对每个ID依次进行webapi调用。这些调用不应并行,而应链接在一起。 有问题的函数返回自己一个“主要”的承诺,该承诺应根据异步Web调用的结果来解决或拒绝。也

  • 问题内容: 关于这两个重要来源:NZakas- 承诺链中的归还承诺 和MDN承诺,我想提出以下问题: 每次我们从承诺履行处理程序返回值时,该值如何传递给从同一处理程序返回的新承诺? 例如, 在这个例子中,是一个承诺。也是来自履行处理程序的承诺。但是。取而代之的是神奇地解决(如何?),然后将该值传递给的实现处理程序。即使是这里的句子也令人困惑。 您能给我解释一下这到底是怎么回事吗?我对这个概念感到困

  • 问题内容: 比不同的。它支持普通用户可以执行的所有操作以及许多其他功能。 我正在将我的应用程序从更改为。但是我不太知道如何以编程的方式注入函数- 我在外部和外部使用的代码。 因此,使用standard ,我可以在运行块中动态注入我的代码: 现在,我如何使用类似的方式注入解决承诺?我尝试通过以获取对的访问权限,但这对我来说是失败的。 问题答案: 您可以用来在加载下一个状态之前为控制器提供数据。要访问