如何让JavaScript多函数按序同步执行?Promise实现示例
如何用Promise实现JavaScript多函数的顺序同步执行
当然可以用Promise来解决这个问题!你的场景里两个函数都包含异步HTTP请求,而AngularJS的$http本身就返回Promise,正好可以利用这一点来实现顺序执行。我来一步步给你改造代码:
第一步:让异步函数返回Promise
首先,我们需要让updateStartJobManual和addProfSms返回它们内部$http调用的Promise,这样我们才能控制执行顺序:
改造updateStartJobManual
function updateStartJobManual() { // 返回$http请求的Promise return $http({ method: 'POST', url: '/api/updatestartjobmanual', data: $scope.draft }).then(function(response) { $scope.currentItem = response.data; $scope.todos[$scope.currentItemIndex] = response.data; $scope.editMode = false; console.log('draft:', response.data); $state.reload(); // toastr.success('Updated Successfully'); }, function(response) { console.log('error'); // 抛出错误,让后续的catch能捕获到 return Promise.reject(response); }); }
改造addProfSms
function addProfSms() { // 返回$http请求的Promise return $http.post('/api/sendprofsms', $scope.draft).then(function(response) { swal("Good job!", "Message sended!", "success") // $state.reload(); }); }
改造byeSendManualInputDirectly
这个函数里有同步的confirm弹窗,我们需要手动创建一个Promise来包裹它的逻辑,让它也能成为一个Promise兼容的函数:
function byeSendManualInputDirectly() { return new Promise(function(resolve, reject) { if ($window.confirm("Do you want to send this messages?")) { // 用户确认时,调用addProfSms并传递它的Promise结果 addProfSms().then(resolve).catch(reject); } else { console.log('no'); // 用户取消时,直接resolve让流程继续 resolve(); } }); }
第二步:修改主函数实现顺序执行
现在我们可以用Promise的链式调用,或者async/await来实现先执行updateStartJobManual,完成后再执行byeSendManualInputDirectly:
方式1:Promise链式调用
$scope.saveManualResendDraft = function(todo) { if ($scope.editMode) { updateStartJobManual() .then(function() { // 第一个函数执行完成后,再调用第二个函数 return byeSendManualInputDirectly(); }) .catch(function(error) { // 捕获任何一步出现的错误 console.error('执行过程中出错:', error); }); } else { console.log('bye'); } };
方式2:async/await(ES2017+环境支持)
如果你的项目环境支持ES2017及以上的语法,用async/await会让代码更简洁易读:
$scope.saveManualResendDraft = async function(todo) { if ($scope.editMode) { try { // 等待updateStartJobManual执行完成 await updateStartJobManual(); // 再执行byeSendManualInputDirectly await byeSendManualInputDirectly(); } catch (error) { console.error('执行过程中出错:', error); } } else { console.log('bye'); } };
原理说明
Promise的核心就是用来处理异步操作的顺序执行:
$http返回的Promise会在请求完成(成功或失败)时改变状态- 通过
.then()可以指定上一个异步操作完成后要执行的下一个操作 async/await是Promise的语法糖,让异步代码看起来像同步代码一样直观
内容的提问来源于stack exchange,提问作者Sameer
相关产品推荐
相关产品推荐

