在 for 循环中等待函数结果

wait for a function result in a for loop

我正在使用 AngularJs 和模块 ngSweetAlert http://oitozero.github.io/ngSweetAlert/#/home,我必须等待 for 循环中确认按钮函数中指令的执行:

for (var i = 0; i < myArray.length; i++) { 
    SweetAlert.swal({
        title: "Are you sure?",
        text: "Your will not be able to recover this imaginary file!",
        type: "warning",
        showCancelButton: true,
        confirmButtonColor: "#DD6B55",
        confirmButtonText: "Yes, delete it!",
        cancelButtonText: "No, cancel plx!",
        closeOnConfirm: false,
        closeOnCancel: false
    }, function(isConfirm) { 
        if (isConfirm) {
            // Instructions using myArray
        } else {

        }
    });
}

使用承诺:

var deferred = $q.defer();
q.resolve(isConfirm); // or whatever ur data is
return deferred.promise;

然后使用"then"指定应该对返回的承诺的结果做什么;

yourFn().then(function(isConfirm){
  //do stuff
});

编辑:正如 Andrew Luhring 所指出的那样,原始轮询示例不正确

以下是如何使用异步回调样式在前者完成后安排每个警报弹出窗口:

function showAlertNTimes(n) {
    if (n > 0) {
        SweetAlert.swal({...}, function() {
            // Do confirmation stuff 
            showAlertNTimes(n - 1); 
        });
    }

}
showAlertNTimes(myArray.length);

小心,未经测试

不熟悉 swal,但快速查看它的源代码后它似乎没有提供承诺,所以我写了一个小包装器(基于 src,在链接的演示页面上):

//since swal doesn't implement promises on it's own, here a wrapper that returns one
function $swal(title, message, type){
    return typeof message === "function"?  $swal(title).then(message):
        typeof title !== "object"? $swal({ title:title, message:message, type:type }):
        config => $q(function(resolve){ window.swal(config, resolve) });
}

这应该像常规交换函数一样运行,只是它 returns 一个承诺。需要来自 angular 的 $q 和初始化的 SweetAlert

现在异步变得简单了:

myArray.reduce(function(prev, value, index, arr){
    //wait till the previous promise has been resolved, 
    //then resolve the this one
    return prev.then(function(){
    //return prev.catch(/* error handling for prev */).then(function(){

        //utilize the wrapped function. 
        return $swal({
            title: "Are you sure?",
            text: "Your will not be able to recover this imaginary file!",
            type: "warning",
            showCancelButton: true,
            confirmButtonColor: "#DD6B55",
            confirmButtonText: "Yes, delete it!",
            cancelButtonText: "No, cancel plx!",
            closeOnConfirm: false,
            closeOnCancel: false
        //}).then(function(isConfirm){
        }, function(isConfirm){  //this is just an alias for the previous line
            console.log(index, isConfirm, value);
        });
    });
}, $q.resolve(true));

我传递了一个已解决的 Promise,所以我不必处理它是第一个调用还是从属调用。

reduce 还包装了每次调用的当前索引和值。

还有一件事尚未处理,即您的代码是否会抛出错误。

编辑: 正如 4castle 在评论中指出的那样,SweetAlert2 似乎实现了承诺。
好吧,那么您根本不需要 $swal-wrapper,而是使用带有 reduce 的常规 swal-function。