我正在开发基于以太坊的Dapp,但对Promises感到困惑。

在for循环中,必须逐一验证数组的元素。这发生在validateRow()函数中,该函数首先返回Promise。 Promise将解析为一个数字(元素有效时为0;无效时为1、2或3)。

最后,我想返回一个resultList[],它是一个对象数组。每个对象应具有两个属性:


row,包含元素(字符串),
result,告诉它是否有效。


但是,resultList[]仅包含末尾的行,而'then'分支仅保存结果({"row":"","result":"0"})。我添加了作为注释打印在控制台中的日志。不幸的是,我不知道如何将两者结合在一起。

var resultList = [];
for (var i = 0; i < App.resultArray.length; i++) {

    var promiseReturned = contractInstance.validateRow.call(App.resultId, App.resultArray[i]);
    console.log(promiseReturned); //Promise {<pending>}

    var rowObject = new Object();
    console.log(App.resultArray[i]); //row1string
    rowObject.row = App.resultArray[i];

    promiseReturned.then(function(returnVal) {
        console.log("the returnVal: " + returnVal); //the returnVal: 1
        rowObject.result = returnVal;
        console.log("the rowObject :" + JSON.stringify(rowObject)); //{"row":"","result":"0"}
        return returnVal;
        });
        resultList.push(rowObject);
};
console.log(resultList); //[{"row":"row1string"},{"row": "row2string"}]
return resultList;

最佳答案

在Javascript中,使用正斜杠表示注释,而不是反斜杠,否则会出现语法错误。

在返回对象之前,使用Promise.all等待所有承诺都得到解决:

async function getResultList() {
  const allPromises = App.resultArray.map((row) => (
    contractInstance.validateRow.call(App.resultId, row)
      .then(result => ({ result, row }))
  ));
  const resultList = await Promise.all(allPromises);
  return resultList; // This will return a Promise to the caller of getResultList
}


请注意,您必须使用getResultList作为约定,因为它不能同步运行。例如

const resultList = await getResultList();

09-16 08:06