javascript - 访问 Promise .then 在 Promise 之外返回的值

标签 javascript node.js promise react-redux

标题说明了一切,我正在使用 async-library eachSeries 方法

let 
  valueOne = null,
  validItem = null;

const asyncEachSeries = require('async/eachSeries');

const getContent = function (item) {
  contentResponse = fetchContent(item);
  return contentResponse;
}

if (recommendationsArr.length > 0) {
  asyncEachSeries(recommendationsArr, function (item, callback) {
    getApiContent(item).then(function getValidResult(response) {
      try { 
        valueOne = response.content.valueOne || null; //may or may not be present
        recommendationsArr.splice(recommendationsArr.indexOf(item), 1); 
        validItem = item;
        console.log("##### valueOne is: ", valueOne); // I get data here
        return true;
      } catch (err) {
        valueOne = null;
        return false;
      }
    });
    //I am guessing I need a return statement here, though not sure what
  });

  console.log("##### Outside promise, valueOne is: ", valueOne); // no data here

  // Access valueOne, validItem, recommendationsArr to be able to pass as props for the component 
  return {
    component: <Layout><ComponentName
      //pass other non-dependent props
      validItem={validItem}
      valueOne={valueOne}
      recommendationsArr={recommendationsArr}
    /></Layout>,
    title: `Page Title`,
  };
}

return null;

场景:recommendationsArr 是一个项目数组(它 99.9% 不为空,但由于它是外部 api 调用,我更喜欢进行检查)。目的是获得 valueOnevalidItem 的值以及更新的 recommendationsArr
有效性取决于 valueOne 是否存在,因此如果 recommendationsArr[0] 具有有效的 valueOne 那么我不需要为数组的其余部分获取 api 结果。我使用 eachSeries 因为它一次只运行一个异步操作,因此,如果该异步为我提供了有效结果,我就不必迭代其他项目。

示例commendationsArr:recommendationsArr = ["blue", "white", "green", "red"];//通常数组包含 12-50 个元素

现在,为了能够将更新的值传递给组件,我需要能够访问 asyncEachSeries 迭代循环之外的 try block 中设置的值。我知道我必须返回已处理/新值,但不确定在什么时候以及如何返回这些值。

最佳答案

与任何有关异步代码的问题一样,您可以使用回调返回值。但 eachSeries 不收集返回值。你想要的是async.mapSeries:

async.mapSeries(recommendationsArr, function (item, callback) {
  getApiContent(item).then(function (response) {
    try { 
      valueOne = response.content.valueOne || null; //may or may not be present
      recommendationsArr.splice(recommendationsArr.indexOf(item), 1); 
      validItem = item;
      callback(null, valueOne); // This is how you return a value
      // return true; // return does absolutely nothing
    } catch (err) {
      valueOne = null;
      callback(err, valueOne);
      // return false;
    }
  });
},function (err, result) {
  // this is where you can process the result
  // note that the result is an array
});

但是,由于您使用的是 Promise,因此您可以使用 async-q 来代替,它将 caolan 的异步库包装在 Promise 中:

var asyncQ = require('async-q');

asyncQ.mapSeries(recommendationsArr, function (item) {
  // Note: the return in the line below is important
  return getApiContent(item).then(function (response) {
    try { 
      valueOne = response.content.valueOne || null; //may or may not be present
      recommendationsArr.splice(recommendationsArr.indexOf(item), 1); 
      validItem = item;
      return valueOne; // this is how you return a value in a promise
    } catch (err) {
      return null
    }
  });
})
.then(function(result) {
  // you can process the result here
});

就我个人而言,我更愿意重写代码并在最后处理结果,因为代码更干净:

asyncQ.mapSeries(recommendationsArr, getApiContent)
  .then(function (result) {
    for(var i=0;i<result.length;i++) {
      var response = result[i];
      // do what needs to be done with each response here
    }
  });

关于javascript - 访问 Promise .then 在 Promise 之外返回的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43219739/

相关文章:

javascript - 为什么通过 iOS Twitter 浏览器访问网页时 javascript 无法在网页上执行?

javascript - 我怎样才能停止 AJAX 调用保持 PHP session 事件

node.js - 用于散列和加盐用户登录/密码的好 npm 模块?

javascript - Angular 从服务返回 promise 对象。尝试访问值来更改 ng-if 指令

node.js - 从 KOA 中间件内部的 Promise 调用 Yield

javascript - 按值查找数组中的对象并更新整个对象

javascript - initNumToRender 如何在 FlatList 上工作?

javascript - 为什么下面的setTimeout直接打印出来了?

javascript - async.each 有问题,回调在完成任务之前被调用

javascript - 等待循环内的 promise