javascript - 如何用Q嵌套序列?

标签 javascript promise q

我想处理一系列任务,并在其中一部分任务完成以及每项任务完成后立即收到通知。我期望的输出应该是1,2,3 - 4,5,6 - 7 - 8。通过我当前的实现,我得到 1,4,7,8 - 2,5 - 3,6

function handleTasks(tasks) {
    var deferred = Q();
    var promises = []

    tasks.forEach(function (task) {
        promises.push(function () {
            return handle(task);
        });
    });

    promises.reduce(Q.when, new Q()).then(function () {
        // Finished inner hunk.
        deferred.resolve();
    });

    return deferred.promise;
}

function handle(t) {
    var deferred = Q.defer();
    document.write("started " + t);

    Q.delay(5000).then(function () {
        document.write("finished " + t);
        deferred.resolve();
    });

    return deferred.promise;
}

var deferred = Q();
var tasks = [[1, 2, 3], [4, 5, 6], [7], [8]];
var promises = []

tasks.forEach(function (task) {
    promises.push(function () {
        return handleTasks(task);
    });
});

promises.reduce(Q.when, new Q()).then(function () {
    // Finished all tasks
    deferred.resolve();
});
<script src="http://cdnjs.cloudflare.com/ajax/libs/q.js/0.9.6/q.js"></script>

最佳答案

我真的不确定你的代码是如何产生任何输出的。您尝试使用 promise ,就好像它们是延期的一样,并且您正在使用 document.write(),我想这会覆盖您的整个页面。

虽然不一定是错误,但您正在使用 deferred antipattern .

所以我不太确定为什么你会得到这样的结果,但这里有一个更干净的方法可以产生所需的结果:

function handleTasks(tasks) {
    var promiseFuncs = tasks.map(function (task) {
        return function () {
            return handle(task);
        };
    });

    return promiseFuncs.reduce(Q.when, new Q()).then(function () {
        console.log("finished " + JSON.stringify(tasks));
    });
}

function handle(t) {
   console.log("started " + t);

    return Q.delay(5000).then(function () {
        console.log("finished " + t);
        return t;
    });
}

var tasks = [[1, 2, 3], [4, 5, 6], [7], [8]];
var promiseFuncs = tasks.map(function (task) {
    return function () {
        return handleTasks(task);
    };
});

promiseFuncs.reduce(Q.when, new Q());
<script src="http://cdnjs.cloudflare.com/ajax/libs/q.js/0.9.6/q.js"></script>

您还可以使用辅助函数消除此处的一些重复:

function runSequence(items, action) {
    return items.map(function (item) {
        return function () {
            return action(item);
        };
    }).reduce(Q.when, new Q());
}

function handleTasks(tasks) {
    return runSequence(tasks, handle).then(function () {
        console.log("finished " + JSON.stringify(tasks));
    });
}

function handle(t) {
   console.log("started " + t);

    return Q.delay(5000).then(function () {
        console.log("finished " + t);
        return t;
    });
}

var tasks = [[1, 2, 3], [4, 5, 6], [7], [8]];
runSequence(tasks, handleTasks);
<script src="http://cdnjs.cloudflare.com/ajax/libs/q.js/0.9.6/q.js"></script>

关于javascript - 如何用Q嵌套序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28438261/

相关文章:

javascript - 理解 promise 链接 : 'then()' get's undefined parameter as the result

javascript - 在javascript中映射嵌套数组中的非对象值

javascript - PWA 推送通知。消息仅出现在控制台中。

javascript - Ajax从函数获取验证,然后将响应传递给另一个ajax?

javascript - 确定 promise 需要多长时间

javascript - 控制流程和 promise

javascript - 返回静态值作为 promise

javascript - nodejs、passportjs 和sequelize 与passport-local

javascript - 等号与箭头函数有何关系?

javascript - iOS 12 浏览器 : Is there a way to make web-based QR Scanning work?