Как использовать обещания, когда мне нужны различные возвращаемые значения [дубликаты]

У меня есть эта функция, которая использует обещания и работает правильно:

parse: function (fileAsString, options) {
        return when.promise(function(resolve, reject){
            if (fileAsString.length) {
                var metaData = options || {};
                var points = extractPointsFromPCD(fileAsString);
                var cleanedPoints = cleanPoints(points);
                var cordsAndRGBs = createCoordinateAndRGBObjects(cleanedPoints);
                var res = removeExtremePoints(3, cordsAndRGBs);

                var pcdContainer = {
                    coordinateAndRGBObjs: res.points,
                    average: res.average,
                    metaData: metaData,
                    fileString: fileAsString
                };
                // TODO: do meaningful test
                if(res && res.points && res.average && metaData && fileAsString){
                    resolve(pcdContainer);
                } else {
                    // TODO: add actual error
                    reject("something went wrong");
                }
            } else {
                console.log(LOG + "No file!");
            }
        });
    }

Как видите, каждая функция возвращает значение, которое мне нужно использовать в следующей функции. Но мне также нужно агрегировать различные возвращаемые значения, поскольку именно их должна возвращать функция синтаксического анализа. removeExtermePoints даже возвращает объект!

Я был на пути к рефакторингу функции синтаксического анализа, чтобы подфункции также использовали промисы, когда я не был уверен, что делать дальше. Код, который у меня был, выглядел примерно так:

parse: function (fileAsString, options) {
    return when.promise(function(resolve, reject){
       if (fileAsString.length) {
          var metaData = options || {};

        extractPointsFromPCD(fileAsString)
            .then(cleanPoints)
            .then(createCoordinateAndRGBObjects)
            .then(removeExtremePoints)
            .done(function(pcdContainer){
                resolve(pcdContainer);
            });

    } else {
        reject(LOG + "No file to parse!");
    }
});
}

Вопрос 1

У меня больше нет ссылок на одиночные возвращаемые значения. Я предполагаю, что мог бы просто использовать объект, который я передаю в первое обещание, продолжать проталкивать его через все последующие, добавляя значения и возвращая это, но я не уверен, что это хороший способ получить то, что у меня было в разум в первом фрагменте?

Вопрос 2

removeExtremePoints принимает фактор в качестве входных данных, и я хочу, чтобы так и оставалось. Я предполагаю, что могу использовать resolve(3, result) в createCoordinateAndRGBObjects? Мне это очень не нравится, потому что вдруг функция createCoordinateAndRGBObjectsопределяет, как я хочу запустить removeExtremePoints, я бы лучше определил параметр в теле разбора.

Кроме того, что, если в какой-то момент я что-то изменю, может быть, обещание после createCoordinateAndRGBObjects не будет removeExtremepoints для другого варианта использования. Как бы я поступил?


person MJB    schedule 13.10.2014    source источник
comment
Мне просто любопытно, почему вы вообще используете обещания здесь. Я не вижу никаких асинхронных операций. Похоже, вы слишком усложнили ситуацию, и это может быть просто процедурная функция, которая возвращает структуру данных.   -  person jfriend00    schedule 14.10.2014
comment
Я хочу использовать промисы в других местах, и это всего лишь самый простой сегмент кода, где я хочу прощупать почву с помощью промисов. При этом я думаю, что код во втором фрагменте выглядит чище и понятнее.   -  person MJB    schedule 14.10.2014
comment
Если вы считаете, что использование промисов, когда они не нужны, упрощает ваш код, то вы имеете право на свое мнение. Я не обнаружил, что написание синхронного кода в асинхронном стиле проще, легче или менее подвержено ошибкам — как раз наоборот. И, конечно, он не работает так же хорошо. Кроме того, ваш второй блок кода на самом деле тоже не работает, потому что вы нигде не отслеживаете все промежуточные данные.   -  person jfriend00    schedule 14.10.2014
comment
да я знаю что второй блок не работает. Как я указал в своем посте, это было то, к чему я его рефакторил, когда понял, что у меня больше нет доступа к различным возвращаемым значениям, а также нет четкого представления о том, как передать 3 в removeExtremePoints. Я просто использую это как упражнение, чтобы узнать кое-что о том, как правильно использовать промисы в подобном случае. Можно просто представить, что все эти функции были асинхронными, и у меня было 4 вложенных обратных вызова.   -  person MJB    schedule 14.10.2014
comment
И когда вы начнете отслеживать все различные возвращаемые значения, ваш второй блок кода будет больше похож на ваш первый блок, но с дополнительной сложностью вызовов .then() и асинхронным поведением. Лично я думаю, что вы немного заблуждаетесь относительно того, для чего лучше всего использовать промисы, а для чего лучше просто придерживаться традиционной функции, которая выполняет несколько вызовов других функций.   -  person jfriend00    schedule 14.10.2014
comment
Я просто использую это как упражнение, чтобы узнать кое-что о том, как правильно использовать промисы в подобном случае. Можно просто представить, что все эти функции были асинхронными, и у меня было 4 вложенных обратных вызова.   -  person MJB    schedule 14.10.2014
comment
Я писал о чем-то подобном здесь. Он использует синтаксис Bluebird, который, на мой взгляд, лучше, но это можно сделать и в when.js, используя .all и .spread (.join в этих библиотеках разные)   -  person ldmat    schedule 14.10.2014
comment
о, хорошо, есть ли способ связать этот ответ с моим постом или мне просто удалить свой? Я думаю, это то, что я искал. Это, как говорится, все еще довольно грязно в конце.   -  person MJB    schedule 14.10.2014