向数组添加多个回调响应

Add multiple callback responses to array

本文关键字:回调 响应 数组 添加      更新时间:2023-09-26

我有这个称为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);
    }
}

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

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

如果您使用的所有函数都是同步的,并且实现方式与以下类似,那么您的代码就可以很好地工作:

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()"等待"直到这些部分完成。也许可以将它们包装在另一个回调中?

如果checkForUniqueURLcheckForCustomURL函数是同步的,这将工作。下面是它同步函数一起工作的例子…

https://jsfiddle.net/ojh5b1f8/

然而,我将假设,因为它不起作用,你的函数是异步的。这里有一个例子,它不工作异步函数…

https://jsfiddle.net/uzjbyrt7/

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

https://jsfiddle.net/ynxcu7t6/