2017-10-05 82 views
0

之前,我有一个要求做到以下几点:JavaScript的诺言 - 等待清晰度的运动上

  1. 通过调用内部函数获取的“线”的列表(getLines())。
  2. 选择第一行,执行一个动作
  3. 以往的动作完成后,选择下一行,做同样的动作
  4. 重复所有线路(3-20取决于用户)

我有下面的代码代替:

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); 
    }); 
} 

我的希望是,循环将等待解决的承诺,它继续循环之前,然而,事实并非如此。 我的问题是在分辨率完成之前是否可以暂停循环。 注 - 我正在使用蓝鸟JS库作为承诺。 谢谢!

亲切的问候,

加里

+0

我认为你必须以某种方式“返回”承诺。就像在这种情况下,“履行”是你在诺言中使用的关键词。 – ZombieChowder

+0

而不是循环整个事情,循环makeCallPromise并将这些承诺推送到一个数组。然后使用Promise.all(array)并在promise.all后添加'then()'调用。结果将会是所有的promsies都会在调用第一个'then()'之前解析,所以所有的数据都可以重新循环。或者,根本不要使用循环,但在前者解析后进行下一次makeCallPromise。 – Shilly

+0

@Shilly谢谢,我已经尝试在由marvel308提供的答案中使用此方法,并使用Promise.each()。我的回应是关于我所做的和发生的事情。 – Gary

回答

0

可以使用Promise.each()通过蓝鸟提供,这将依次遍历数组,并等待他们移动到下一个元素的数组

+0

我已经尝试通过迭代承诺并创建它们的数组(而不是在迭代中解决它们)。然后我调用Promise.each(promiseArray,function(result){console.log(result)}。然后(function(fulfilled){console.log(“WORKED”)})。catch(function(error){的console.log( “ERROR”)}));”。问题是这不起作用,它仍然尝试执行Session.connection.ol.makeCall而不等待第一个解决。 – Gary

+0

你使用蓝鸟吗? – marvel308

+0

嗯我已经通过将它包含在

0

我在之前解决不知道蓝鸟,但你可以做类似的事情来创建某种for循环,等待每个承诺在下一次迭代之前结束。

这是一个普通的例子,它当然可以进行优化,它只是一个快速的尝试:

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); 

希望这会帮助你;)

0

这个用例完全匹配的ES7功能async await,如果您在使用babeljs到transpile你的代码的可能性,你可以重构你的函数是这样的:

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'); 
}); 
0

您应该使用Bluebird#each方法:

。每个(函数(任何项目,INT索引,INT长度)迭代) - >无极

迭代数组或数组,其中包含的承诺一个承诺(或与给定的具有签名(值,索引,长度)的迭代器函数的承诺和值的组合),其中值是输入数组中相应承诺的解析值。迭代发生连续。如果输入数组中的任何承诺被拒绝,返回的承诺也会被拒绝。

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)); 
}); 
+0

嗨,这不起作用,我真的不明白它在做什么。在1行值的简单情况下,它看起来像在同一时刻发出两次'Session.connection.ol.makeCall',所以我们立即失败。当我将它更新为2行时,它会立即发出4个'Session.connection.ol.makeCall',然后在响应返回后再发出2个。 – Gary

+0

根据你的问题中的代码,'App.Lines'是一行数组,在我的代码中,我使用'Bluebird#each'方法遍历数组,并为每一行调用'Session.connection.ol.makeCal'。你确定'App.Lines'在第一种情况下有一行(一个元素),第二种情况下有两行?在Promise.each之前添加'console.log(App.Lines.length)'。 – alexmac