8

プロミスを順番に実行するのに苦労しています。

var getDelayedString = function(string) {
    var deferred = Q.defer();

    setTimeout(function() {
        document.write(string+" ");
        deferred.resolve();
    }, 500);

    return deferred.promise;
};

var onceUponATime = function() {
    var strings = ["Once", "upon", "a", "time"];

    var promiseFuncs = [];

    strings.forEach(function(str) {
        promiseFuncs.push(getDelayedString(str));
    });

    //return promiseFuncs.reduce(Q.when, Q());
    return promiseFuncs.reduce(function (soFar, f) {
        return soFar.then(f);
    }, Q());    
};

getDelayedString("Hello")
.then(function() {
    return getDelayedString("world!")
})
.then(function() {
    return onceUponATime();
})
.then(function() {
    return getDelayedString("there was a guy and then he fell.")
})
.then(function() {
    return getDelayedString("The End!")
})

onceUponATime() は ["Once", "upon", "a", "time"] を順次出力するはずなのですが、なぜかすぐに出力されてしまいます。

jsFiddle はこちら: http://jsfiddle.net/6Du42/2/

私が間違っていることは何ですか?

4

1 に答える 1

15

代わりに、何らかの理由ですぐに出力されています。

あなたはすでにここでそれらを呼び出しています:

promiseFuncs.push(getDelayedString(str));
//                                ^^^^^

を押す必要がありますfunction(){ return getDelayedString(str); }。ところで、eachループ内で配列へのプッシュを使用する代わりに、使用する必要がありますmap。実際には、とにかくそれは本当に必要ありませんが、配列を直接reduce上書きできます。strings

function onceUponATime() {
    var strings = ["Once", "upon", "a", "time"];

    return strings.reduce(function (soFar, s) {
        return soFar.then(function() {
            return getDelayedString(s);
        });
    }, Q());    
}

ああ、使用しないdocument.writeでください。

于 2013-08-22T17:48:52.637 に答える