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

我要兑现一个承诺。关键是我真的想在第一个诺言兑现后立即访问(仍在等待中的)第二个 诺言

。不幸的是,当两个诺言都实现时,我似乎只能获得第二个诺言的解决值。

这是我想到的用例:

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类型为“功能” 的字段并有条件地包装它。

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

第一个承诺时,才使用上述解决方法。

以上是 用另一个承诺来履行(不解决)承诺 的全部内容, 来源链接: utcz.com/qa/410129.html

回到顶部