JavaScript承诺 - 在继续之前等待解决方案

时间:2017-10-05 08:21:46

标签: javascript for-loop promise bluebird

我要求执行以下操作:

  1. 通过调用内部函数(getLines())获取“行”列表。
  2. 选择第一行,执行操作
  3. 上一个操作完成后,选择下一行并执行相同的操作
  4. 对所有行重复(3-20取决于用户)
  5. 我有以下代码:

    App.Lines = response.data;    
    for (var _i = 0; _i < App.Lines.length; _i++) {
        var makeCallPromise = new Promise(
            function(resolve, reject) {
                Session.connection.ol.makeCall(App.Lines[_i], callBackFunction(response) {
                    //this can take up to 30 seconds to respond...
                    resolve(response.data);
                }, errorCallBackFunction(message) {
                    reject(message.error);
                }, bareJid);
            }
        )
        makeCallPromise.then(function(fulfilled) {
            console.log("PROMISE WORKED!!!!!", fulfilled);
        })
        .catch(function(error) {
            console.log("PROMISE FAILED!!!!!", error);
        });
    }
    

    我希望循环会在继续循环之前等待解决承诺,但事实并非如此。 我的问题是,在解决方案完成之前是否可以暂停循环。 注意 - 我正在使用bluebird JS库进行承诺。 谢谢!

    亲切的问候,

    加里

4 个答案:

答案 0 :(得分:1)

我不了解bluebird,但你可以做类似的事情来创建某种for循环,等待每个promise在下一次迭代之前结束。

这是一个通用示例,它当然可以优化,只是一个快速尝试:

var i = 0;
var performAsyncOperation = function(operationNumber) {
    return new Promise(function(resolve, reject){
    console.log('Operation number', operationNumber);
    resolve();
  });
}

var chainAsyncOperations = function() {
    if(++i < 10) {
        return performAsyncOperation(i).then(chainAsyncOperations);
    }
};
performAsyncOperation(i).then(chainAsyncOperations);

希望这会对你有帮助;)

答案 1 :(得分:0)

你可以使用bluebird提供的Promise.each(),它将串行遍历一个数组并等待它们解析,然后再转移到数组中的下一个元素

答案 2 :(得分:0)

此用例与ES7功能async await完全匹配,如果您可以使用babeljs转换代码,则可以像这样重构您的函数:

function createPromise(line) {
    return new Promise(
       function(resolve, reject) {
          Session.connection.ol.makeCall(line, callBackFunction(response) {
              //this can take up to 30 seconds to respond...
              resolve(response.data);
          }, errorCallBackFunction(message) {
              reject(message.error);
          }, bareJid);
       }
    );
}

App.Lines = response.data;

async function main() {
    for (var _i = 0; _i < App.Lines.length; _i++) {
        try {
           var result = await createPromise(App.Lines[_i]);
           console.log(result);
        } catch (err) {
           console.log(err);
        }
    }
}

main().then(function() {
    console.log('finished');
});

答案 3 :(得分:0)

您应该使用Bluebird#each方法:

  

.each(function(any item,int index,int length)iterator) - &gt;许

     

迭代一个数组或一个数组的promise,它包含promises(或promises和values的混合)和给定的迭代器函数以及签名(value,index,length),其中value是a的解析值输入数组中的相应承诺。迭代按顺序发生。如果输入数组中的任何promise被拒绝,则返回的promise也会被拒绝。

Promise.each(App.Lines, line => {
    return new Promise((resolve, reject) => {
        Session.connection.ol.makeCall(line, callBackFunction(response) {
            resolve(response.data);
        }, errorCallBackFunction(message) {
            reject(message.error);
        }, bareJid);
    })
    .then(fulfilled => console.log("PROMISE WORKED!!!!!", fulfilled))
    .catch(err => onsole.log("PROMISE FAILED!!!!!", err));
});