本文介绍了不理解javascript promise antipattern,从回调中返回promise的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以向我解释为什么在承诺回调中返回承诺会被视为反模式吗?显然它打破了异常冒泡,但显然我对承诺的理解是缺乏的,因为我无法清楚地描述如何工作。我的反模式代码如下:

Could someone explain to me why returning promises in promises callbacks is considered antipattern? Apparently it breaks exception bubbling but obviously my understanding of promises is lacking as I cannot clearly picture how would that work. My antipattern code is below:

var a = new Promise(function (res, rej) {

    setTimeout(function () {
        res("timeout");
    }, 1000);

});

a.then(function (res) {
    console.log("a");
    console.log(res);

    return new Promise(function (res, rej) {
        console.log("b");
        setTimeout(function () {
            res("timeout2");
        }, 2000);
    }).then(function (res) {
        console.log("c");
        console.log(res);

    }).then(function (res) {
        console.log("d");
        console.log(res);

    }, function (res) {
        console.log("e");
        console.log(res);

    });

}).then(function (res) {
    console.log("l");
    console.log(res);
});

编辑:

这个问题是关联的到我的一个我做了类似的承诺和其中一个答案说:

This question is related to one of my previous questions where I do something similar with promises and one of the answers says:

你也必须永远不要将回调与promises混合,因为那样你就会失去异常冒泡(承诺点)并让你的代码超级详细。

所以现在我真的很困惑,如果它是反模式,如果是这样的话。

So now I'm really confused if it is antipattern and if so why.

推荐答案

你也必须永远不要将回调与promises混合,因为那样你就会失去异常冒泡(承诺点)和让你的代码超级详细。

Petka在这里的意思是,你不应该在你的用户代码中使用基于回调的方法和Promises,因为这样做使你的代码非常详细,如你的例子所示。

What Petka means here, is that you should not use callback based methods in your user code together with Promises because this will make your code very verbose, as illustrated by your example.

这是冗长的,因为你每次调用函数时都必须根据回调手动解析或拒绝新的Promise 。

It's verbose because you have to manually resolve or reject a new Promise based on the callback every time you call the function.

setTimeout示例:

您必须在超时完成时手动调用解析程序。
现在setTimeout有点不好,因为它没有可能拒绝它的操作。

setTimeout Example:
You have to manually call the resolver when the timeout completes. Now setTimeout is a bit of a poor example as it does not have a possibility to reject it's operation.

return new Promise(function (resolve, reject) {
        console.log("b");
        setTimeout(function () {
            resolve("timeout2");
        }, 2000);
    })

更好的例子

假设你要打电话给 fs.readFile 像这样:

return new Promise(function (resolve, reject) {
    fs.readFile('foo.txt', function (err, res) {
        if (err){
            reject(err);
            return;
        } else {
            resolve(res);
        }
    });
})

在这里你必须以太解析或拒绝,因为你将承诺与回调混合,这将使你的代码变得非常脆弱和混乱。

Here you have to ether resolve or reject because you are mixing promises with callbacks, this will make your code very brittle and confusing.

解决方案:

无论何时需要调用仅支持的方法,都不要在整个地方创建新的Promise s回调,将基于回调的方法包装一次并在任何地方使用。

Instead of creating new Promises all over the place whenever you need to call a method that only supports callbacks, wrap that callback based method once and use that everywhere.

var readFileAsync = new Promise(function (resolve, reject) {
    fs.readFile('foo.txt', function (err, res) {
        if (err){
            reject(err);
            return;
        } else {
            resolve(res);
        }
    });
});

奖金:

你甚至不需要这样做包裹你的自己,蓝鸟已经让你满意。
结帐时,我们会在这里结账:

You don't even need to do this wrapping your self, bluebird has got you covered.Checkout promisification right here:

这整个说明除了在promise的 onFulfilled 方法中返回Promise完全有效之外。
这是Promise / A +规范的一部分,请参阅承诺解决程序 - > 2.3.2如果x是承诺,采用其状态[[3.4](#notes)]:

This whole explanation is sort of beside the fact that it is completely valid to return a Promise inside a promise's onFulfilled method.This is part of the Promise/A+ spec, see the The Promise Resolution Procedure -> 2.3.2 If x is a promise, adopt its state [[3.4](#notes)]:

我认为你的困惑源于Petka告诉你不要的事实在您的示例中创建并返回新的承诺。但这与你回归Promise的事实无关,而是与你不应该在那个地方创造承诺的事实有关,如上所述。

I assume your confusion originates from the fact that Petka is telling you not to create and return new promises in your example. But this has nothing to do with the fact that you are returning Promises, but rather with the fact that you shouldn't be creating promises at that place, as stated here above.

使用包装版本,然后您可以在任何地方返回/链接它们。

Use a wrapped version, and then you are good to return/chain them wherever you want.

这篇关于不理解javascript promise antipattern,从回调中返回promise的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-16 08:29