JS Promise:返回映射数据

时间:2017-01-31 07:17:27

标签: javascript callback promise

我有一个功能" mapTranslations"从服务器获取数据然后映射它。目前我使用回调来返回数据。我不想使用承诺 - 我不知道如何返回映射数据,而不是来自" somePromiseReturningFunction"的数据。

function mapTranslations(callback){
    somePromiseReturningFunction(...).then(function (languageData) {
        var translations = {};
        languageData.d.results.forEach(function (obj) {
            translations[obj.key] = obj[browserLang];
        });
        callback(translations);
    });
}

像这样使用它:

mapTranslations(function(translations){
    console.log(translations);
});

目标:

mapTranslations().then(function(translations){
    console.log(translations) //Example, wouldn't be an anonymous function
});

2 个答案:

答案 0 :(得分:1)

我建议您返回原始承诺并从.then()处理程序返回一个值(如下所示):

function mapTranslations(){
    return somePromiseReturningFunction(...).then(function (languageData) {
        var translations = {};
        languageData.d.results.forEach(function (obj) {
            translations[obj.key] = obj[browserLang];
        });
        return translations;
    });
}

// usage
mapTranslations().then(function(results) {
     // access results here
}).catch(function(err) {
     // handle error here
});

当您从.then()处理程序返回一个值,该处理程序将成为返回的promise的已解析值,并且调用者将看到该值。因此,您可以修改原始承诺的返回值,并将其返回到您自己的.then()处理程序中。

此外,你真的不希望在回调中包装一个promise。这只是抛弃了承诺的所有优点(链的能力,自动异步错误传播,管理/协调多个异步操作的能力,与其他异步操作的互操作性等等)。相反,只需返回promise并让调用者对返回的promise使用.then()即可访问数据或错误。仅供参考,在您提出的回调代码中,您正在默默地吃掉来自somePromiseReturningFunction()的任何错误。如果它拒绝它返回的承诺,你就没有处理程序,所以调用者永远不会知道。如果您只是从函数中返回承诺,那么错误处理是免费的。

仅供参考,您可能希望使用.reduce()代替.forEach(),因为它与您正在做的事情保持一致:

function mapTranslations(){
    return somePromiseReturningFunction(...).then(function (languageData) {
        return languageData.d.results.reduce(function(translations, obj) {
            translations[obj.key] = obj[browserLang];
            return translations;
        }, {});
    });
}

答案 1 :(得分:1)

这样的事情应该做,then可以返回一个值,并返回一个你可以使用的新承诺。

function mapTranslations(){

    return somePromiseReturningFunction(...).then(function (languageData) {
        var translations = {};
        languageData.d.results.forEach(function (obj) {
            translations[obj.key] = obj[browserLang];
        });
        return translations;
    });

}

mapTranslations().then( .... ).catch( ... );