Javascript 在解析下一个承诺之前,以$q解析每个承诺中的整个链

Javascript 在解析下一个承诺之前,以$q解析每个承诺中的整个链,javascript,angularjs,Javascript,Angularjs,我在一个数组中循环,在每个循环中,我添加一个承诺数组,然后将其传递到$q.all。每个链包括一个confirm()对话框和一个modal。用户的事件顺序应为confirm()-modal-confirm()-modal。相反,我得到的是confirm()-confirm()-modal-modal。另外,我希望在关闭最后一个模式后执行函数refreshSelection(),但当前它会在关闭最后一个confirm()对话框后立即启动 var promiseArr = []; va

我在一个数组中循环,在每个循环中,我添加一个承诺数组,然后将其传递到
$q.all
。每个链包括一个
confirm()
对话框和一个
modal
。用户的事件顺序应为confirm()-modal-confirm()-modal。相反,我得到的是confirm()-confirm()-modal-modal。另外,我希望在关闭最后一个模式后执行函数
refreshSelection()
,但当前它会在关闭最后一个
confirm()
对话框后立即启动

    var promiseArr = [];
    var selection = []; // [obj1, obj1, obj3...]

    for (var i = 0; i < selection.length; i++) {
        promiseArr.push(getData(i));
    }

    $q.all(promiseArr)
        .then(refreshSelection);

    function getData(i) {
        var opts = {}; // selection[i].id is param

        return $http(opts)
            .then(onGetSuccess(i));
    }

    function onGetSuccess(i) {
        return function(result) {
            var shouldOpenModal = confirm(selection[i].text);

            if (shouldOpenModal == true) {
                openModal();
            }
        }
    }

    function openModal() {
        var copyPunchesModal = $uibModal.open({
            // modal template options
            }
        });

        copyPunchesModal.result.then(otherFunc, function () {
            console.log("Modal closed");
        });
    }

    function refreshSelection() {
        selection = [];
    }

非常感谢您的帮助。

您希望使用$.when函数,该函数将许多承诺作为参数,并在它们全部完成时执行一个函数。或者,如果您同意按顺序完成,可以将它们全部管道连接在一起


Q.all没有指定承诺的解决顺序。如果希望按照数组的顺序完成承诺,则需要链接承诺,以便在前一个承诺的.then()内执行当前承诺

您可以使用reduce干净地执行此操作

,这里它适用于Q:

deferred = $q.defer();
deferred.resolve();
return selection.reduce(
    (accumulator, current) => accumulator.then(()=>getData(current)), 
    deferred.promise
);

请注意,您还需要修改getData函数,以便对对象本身进行操作(例如,使用
currentSelection.text
而不是
selection[i].text

我想做一些类似的事情,以避免程序控制的设备溢出-基本上,我需要等待异步事务完成,然后再开始下一个事务。我使用承诺来强制执行执行顺序,并阻止执行,直到每个项目都完成

// the async thing we want to do, wrapped in a promise
//
function sendMessage = (message) {
    var promise = new Promise (resolve, reject) {
        // send message via an async function that provides success & fail callbacks, e.g. AJAX
        // replace 'asyncFunction', it's just a placeholder in this example
        asyncFunction (message, 
            function (response) {   // success callback
                if (/*response is to my liking*/) {
                    resolve ();
                } else {
                    reject (new Error (/*why I didn't like the response*/));
                }
            },
            function (error) {  // failure callback
                reject (error);
            }
    };
    return promise;
}

// the array we want to process in order
var myMessages = ['hello', 'world', 'how', 'are', 'you', 'today?'];

// iterator, and recursive function to loop thru array
var idx = 0;
function next () {
    if (idx < myMessages.length) {
        sendMessage (myMessages[idx++]).then (
            next,   // maps to the 'resolve' call in sendMessage
            function (err) {    // maps to the 'reject' calls in sendMessage
                throw err;  // clearly, there's an option to be smarter than this
            }
        )
    }
}

// start the recursion
next ();
//我们想要做的异步事情,包装在承诺中
//
函数sendMessage=(消息){
var承诺=新承诺(解决、拒绝){
//通过提供成功和失败回调的异步函数发送消息,例如AJAX
//替换“asyncFunction”,在本例中它只是一个占位符
异步函数(消息,
函数(响应){//成功回调
如果(/*响应符合我的喜好*/){
决心();
}否则{
拒绝(新错误(/*为什么我不喜欢回复*/);
}
},
函数(错误){//失败回调
拒绝(错误);
}
};
回报承诺;
}
//要按顺序处理的数组
var myMessages=['hello'、'world'、'how'、'you'、'today'];
//迭代器和递归函数循环遍历数组
var-idx=0;
函数next(){
if(idx
这是角度,不是jquery。感谢您的回复。当
reduce()时
移动到数组中的第二个元素,累加器是
未定义的
。我删除了arrow函数,希望没有翻译错误。我对promises一般来说也是新手,所以不确定回调是否应该返回不同的内容。这不仅仅是一个arrow函数,这是一个表达式体的arrow函数。正如您所料,这些函数只有一个表达式,因此不需要大括号,但它们也会返回该表达式。让构造函数返回累加器。然后,在reduce中返回的值将被视为下一次执行的累积值,因此如果您不返回任何值,则下一个值是未定义的。感谢您的捕获因此,现在看来
reduce
正在迭代整个数组,但是
getData()
从不执行。应该何时/如何调用它?@devthorne您可以用当前代码更新您的问题,或者发布另一个jsfiddle/pastebin吗?-
getData
从不触发。另外,我假设
refreshSelection()
应该链接到
选择。reduce(…)
因为它返回承诺?--我尝试链接
。然后()
到它,但该函数也不执行。再次感谢。
// the async thing we want to do, wrapped in a promise
//
function sendMessage = (message) {
    var promise = new Promise (resolve, reject) {
        // send message via an async function that provides success & fail callbacks, e.g. AJAX
        // replace 'asyncFunction', it's just a placeholder in this example
        asyncFunction (message, 
            function (response) {   // success callback
                if (/*response is to my liking*/) {
                    resolve ();
                } else {
                    reject (new Error (/*why I didn't like the response*/));
                }
            },
            function (error) {  // failure callback
                reject (error);
            }
    };
    return promise;
}

// the array we want to process in order
var myMessages = ['hello', 'world', 'how', 'are', 'you', 'today?'];

// iterator, and recursive function to loop thru array
var idx = 0;
function next () {
    if (idx < myMessages.length) {
        sendMessage (myMessages[idx++]).then (
            next,   // maps to the 'resolve' call in sendMessage
            function (err) {    // maps to the 'reject' calls in sendMessage
                throw err;  // clearly, there's an option to be smarter than this
            }
        )
    }
}

// start the recursion
next ();