向数组添加多个回调响应

时间:2016-10-23 22:44:22

标签: javascript

我有一个名为checkForURLS的多个函数调用另外两个返回回调的函数,一旦两个回调都返回后如何添加到数组中,然后将数组作为回调返回?我正在使用纯JavaScript。

function checkForURLs(uniqueURL, customURL, callback) {
    var errors = [];

    checkForUniqueURL(uniqueURL, function(UniqueURLCallback) {
        if (UniqueURLCallback===true) {
            errors.push("This unique URL is already taken, please try another.");
        }
    });

    if (customURL.length>0) {
        checkForCustomURL(customURL, function(customURLCallback) {
            if (customURLCallback===true) {
                errors.push("This custom URL is already taken, please try another.");
            }
        });
    }

    if (errors.length>0) {
        return callback(errors);
    } else {
        return callback(false);
    }
}

3 个答案:

答案 0 :(得分:1)

您可以使用Promise构造函数new Promise(function)Promise.all()在调用checkForUniqueURLcheckForCustomURL回调时执行任务。

function callback(value) {
  return value
}

function checkForUniqueURL(url, callback) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(callback(true))
    }, Math.random() * 1500)
  })
}

function checkForCustomURL(url, callback) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(callback(true))
    }, Math.random() * 1500)
  })
}

function checkForURLs(uniqueURL, customURL, callback) {
  var errors = [];

  return Promise.all([
    new Promise(function(resolve, reject) {
      checkForUniqueURL(uniqueURL, function(UniqueURLCallback) {
        if (UniqueURLCallback === true) {
          errors.push("This unique URL is already taken, please try another.");
        } 
        resolve()
      })
    })
  , new Promise(function(resolve, reject) {
      if (customURL.length > 0) {
        checkForCustomURL(customURL, function(customURLCallback) {
          if (customURLCallback === true) {
            errors.push("This custom URL is already taken, please try another.");
          }
          resolve()
        });
      }
    })
  ])
  .then(function() {
    console.log(errors);
    if (errors.length > 0) {
        return Promise.resolve(callback(errors));
    } else {
        return Promise.reject(callback(new Error("false")));
    }
  })
}

checkForURLs("abc", "def", callback)
  .then(function(errs) {
    console.log(errs);
  })
  .catch(function(err) {
    console.log("err:", err.message)
  })

答案 1 :(得分:0)

如果您使用的所有函数都是同步函数并且实现类似于以下函数,则代码可以很好地运行:

function checkForURLs(uniqueURL, customURL, callback) {
    var errors = [];

    checkForUniqueURL(uniqueURL, function(UniqueURLCallback) {
        if (UniqueURLCallback===true) {
            errors.push("This unique URL is already taken, please try another.");
        }
    });

    if (customURL.length>0) {
        checkForCustomURL(customURL, function(customURLCallback) {
            if (customURLCallback===true) {
                errors.push("This custom URL is already taken, please try another.");
            }
        });
    }

    if (errors.length>0) {
        return callback(errors);
    } else {
        return callback(false);
    }
}

// Just test-implement those two functions:
function checkForUniqueURL(url, callback) { callback(true); }
function checkForCustomURL(url, callback) { callback(true); }


errors = checkForURLs("test", "test2", function(errors) {
  console.log(errors);
  return "I have got some errors!";
});

console.log(errors);

如果您的代码确实存在异步部分,则需要使用return callback()“等待”,直到完成。也许将它们包装在另一个回调中?

答案 2 :(得分:0)

这将使IFF checkForUniqueURLcheckForCustomURL函数同步。以下是工作同步函数...

的示例

https://jsfiddle.net/ojh5b1f8/

但是,我将假设,因为它不起作用,你的函数是异步的。以下是使用异步函数无法正常工作的示例...

https://jsfiddle.net/uzjbyrt7/

它不起作用,因为checkForURLs函数在触发回调之前返回。在这种情况下,最好的解决方案是Promises。但是,您可能需要使用库来获得承诺支持,因为它们尚未在所有浏览器中实现。我推荐bluebird.js。这是一个使用异步函数和promises的例子......

https://jsfiddle.net/ynxcu7t6/