当从 for 循环填充变量时如何使用 promise



我有一个函数,可以进行几次异步调用,这些调用用返回的数据填充同一对象。一旦对象完全填充,我需要对数据做一些事情,并且由于有多个调用,这不是基本的回调/承诺场景。

在这种情况下,是否可以创建承诺?简化代码:

price_options = [] // when this is populated from all the async calls, I need to do stuff with it
sheet_columns = [3,5,7,89]
useServiceAccountAuth(credentials, function(error){ //google docs api
  for (var i = 0; i < sheet_columns.length; i++) {
    var params = {column_number: sheet_cols[i]}
    do_async_call(params, function (e, data) {
      data.forEach( function(item) {
        price_options.push(item)
      })
    })
  }
})

其他答案对他们来说有很多错误信息。

你应该做的是使用Promise.all()来聚合所有的承诺。 Promise.all() 采用一个 Promise 数组,并返回一个 Promise,该 Promise 在数组中的所有 Promise 都已解析后解析。

所以现在,你需要创建一个函数来接受每个params条目,并为它上的数据创建一个 Promise,并将其推送到一个新的数组中。

由于我们使用的是 Promises,让我们去掉代码中的所有其他回调:

// The "functionNameAsync" convention indicates that the function returns Promises.
// This convention was coined by Bluebird's promisifying functions.
// Takes credentials
// Returns a promise that rejects on error, or resolves with nothing on no error.
const useServiceAccountAuthAsync = credentials => 
  new Promise((resolve, reject) =>
    useServiceAccountAuth(credentials, err => err ? reject(err) : resolve()));
const doCallAsync = params => 
  new Promise((resolve, reject) =>
    do_async_call(params, (err, data) => err ? reject(err) : resolve(data)));
/* If you opt to use Bluebird, everything above this line can be replaced with:
const useServiceAccountAuthAsync = Promise.promisify(useServiceAcountAuth);
const doCallAsync = Promise.promisify(do_async_call);
it would even be faster than my version above. */
// Now time for the actual data flow:
const sheet_columns = [3,5,7,89]
useServiceAccountAsync()
  .then(() => {
     const arrayOfAsyncCallPromises = sheet_columns
    .map(columnNumber => ({column_number: sheet_cols[columnNumber]}))
    .map(doCallAsync);
  //.map(param => doCallAsync(param)) equivalent to above
     return Promise.all(arrayOfAsyncCallPromises);
  })
  .then(price_options => {
    // use here
  })
  .catch(err => {
    // handle errors here
  });

你需要创建一系列承诺。在这里,您可以了解更多信息。

http://bluebirdjs.com/docs/api/promise.all.html

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

你可以这样做:

let results = sheet_columns.map(c => ({column_number: c}))
    .map(params => new Promise((resolve, reject) => {
    do_async_call(params, (e, data) => {
        if(e) {
            reject(e);
        } else {
            resolve(data);
        }
    })
}))
Promise.all(results).then(arr => Array.prototype.concat.apply([], arr)).then(price_options => doSomething(price_options))

在这里工作 jsbin

如果要

使用 promise,请将 do_async_call 函数包装在 promise 返回函数中。

price_options = [];
sheet_columns = [3,5,7,89]
useServiceAccountAuth(credentials, function(error){ //google docs api
    var promise_array = [];
    for (var i = 0; i < sheet_columns.length; i++){
        var params = {column_number: sheet_cols[i]}
        var promise = do_async_promise(params);
        promise_array.push(promise);
    }
    Q.all(promise_array).then(function(){
    //do your operation with price_options here;
  });
})
function do_async_promise(params){
    var deferred = Q.defer();
    do_async_call(params, function (e, data) {
      data.forEach( function(item) {
        price_options.push(item);
      });
       deferred.resolve();
    })
    return deferred.promise;
}

正如其他研究员所说,Promise.all的使用,我用Promise.all为你写了这个片段,看看。

price_options = [];
sheet_columns = [3,5,7,89];
var promises = [];
useServiceAccountAuth(credentials, function(error){ //google docs api
  for (var i = 0; i < sheet_columns.length; i++) {
    var params = {column_number: sheet_cols[i]}
    // create a new promise and push it to promises array
    promises.push(new Promise(function(resolve, reject) {
     do_async_call(params, function (e, data) {
       resolve(data);
     });
    }));
  }
  // now use Promise.all
  Promise.all(promises).then(function (args) {
    args.forEach(function (data, i) {
       data.forEach(function(item) {
        price_options.push(item)
       });
    });
    // here do your stuff which you want to do with price_options
  });
})

相关内容

  • 没有找到相关文章

最新更新