我如何从函数 foo 返回一个无同步请求的答案/结果?
我正在尝试从呼叫返回的值,以及将结果分配到函数内部的本地变量,并返回其中一个,但没有这些方式实际上返回答案 - 他们都返回不确定的或无论变量结果的初始值是什么。
一个不同步函数的例子,接受召回(使用 jQuery 的 ajax 函数):
function foo() {
var result;
$.ajax({
url: '...',
success: function(response) {
result = response;
// return response; // <- I tried that one as well
}
});
return result; // It always returns `undefined`
}
使用 Node.js 的例子:
function foo() {
var result;
fs.readFile("path/to/file", function(err, data) {
result = data;
// return data; // <- I tried that one as well
});
return result; // It always returns `undefined`
}
例如,使用那时承诺的区块:
function foo() {
var result;
fetch(url).then(function(response) {
result = response;
// return response; // <- I tried that one as well
});
return result; // It always returns `undefined`
}
您可以使用此自定义图书馆(使用 Promise 编写)进行远程通话。
function $http(apiConfig) {
return new Promise(function (resolve, reject) {
var client = new XMLHttpRequest();
client.open(apiConfig.method, apiConfig.url);
client.send();
client.onload = function () {
if (this.status >= 200 && this.status < 300) {
// Performs the function "resolve" when this.status is equal to 2xx.
// Your logic here.
resolve(this.response);
}
else {
// Performs the function "reject" when this.status is different than 2xx.
reject(this.statusText);
}
};
client.onerror = function () {
reject(this.statusText);
};
});
}
简单的使用例子:
$http({
method: 'get',
url: 'google.com'
}).then(function(response) {
console.log(response);
}, function(error) {
console.log(error)
});
让我们先看看森林,先看看树木。
这里有很多有很好的详细信息的答案,我不会重复任何一个。在JavaScript中编程的关键是首先有正确的整体执行的心理模式。
您的输入点(s)是作为一个事件的结果执行. 例如,一个脚本标签与代码被加载到浏览器. (因此,这就是为什么你可能需要担心页面的准备运行你的代码,如果它需要DOM元素首先建造,等等) 您的代码执行完成 - 尽管许多无同步的呼叫它做 - 没有执行任何你的呼叫回复
但你不應該使用任何戰術工具來解決一個問題,直到你很舒服的實際問題領域. 圖描這些依賴的地圖,知道什麼需要執行時。
看看这个例子:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope,$http) {
var getJoke = function(){
return $http.get('http://api.icndb.com/jokes/random').then(function(res){
return res.data.value;
});
}
getJoke().then(function(res) {
console.log(res.joke);
});
});
正如你可以看到 getJoke 返回已解决的承诺(当返回 res.data.value 时,它是解决的)。所以你等到 $http.get 请求完成,然后 console.log(res.joke) 执行(作为正常的无同步流动)。
此分類上一篇: plnkr
http://embed.plnkr.co/XlNR7HpCaIhJxskMJfSg/
ES6路(Async - 等待)
(function(){
async function getJoke(){
let response = await fetch('http://api.icndb.com/jokes/random');
let data = await response.json();
return data.value;
}
getJoke().then((joke) => {
console.log(joke);
});
})();
另一个解决方案是通过序列执行器 nsynjs 执行代码。
nsynjs 将连续评估所有承诺,并将承诺结果列入数据属性:
函数同步Code() { var getURL = 函数(url) { return window.fetch(url).data.text().data; }; var url = 'https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js'; console.log('收到的比特:',getURL(url).length); }; nsynjs.run(同步Code,{},函数(){ console.log('同步Code done'); }; <script src="https://rawgit.com/amaksr/
如果基本功能不承诺
步骤 1 将函数与呼叫回归到 nsynjs-aware 插槽中(如果它有一个有前途的版本,你可以错过这个步骤):
var ajaxGet = function (ctx,url) {
var res = {};
var ex;
$.ajax(url)
.done(function (data) {
res.data = data;
})
.fail(function(e) {
ex = e;
})
.always(function() {
ctx.resume(ex);
});
return res;
};
ajaxGet.nsynjsHasCallback = true;
function process() {
console.log('got data:', ajaxGet(nsynjsCtx, "data/file1.json").data);
}
步骤3:通过 nsynjs 以同步方式运行函数:
nsynjs.run(process,this,function () {
console.log("synchronous function finished");
});
Nsynjs 将逐步评估所有运营商和表达式,如果某些缓慢功能的结果不准备好,则停止执行。
这里有更多的例子。
在阅读这里的所有回复和我的经验后,我希望重复在JavaScript中无同步编程的呼叫、承诺和Async/等待的细节。
const body = document.getElementsByTagName('body')[0];
function callback() {
console.log('Hello');
}
body.addEventListener('click', callback);
asyncCallOne(function callback1() {
asyncCallTwo(function callback2() {
asyncCallThree(function callback3() {
...
})
})
})
const myFirstPromise = new Promise((resolve, reject) => {
// We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed.
// In this example, we use setTimeout(...) to simulate async code.
// In reality, you will probably be using something like XHR request or an HTML5 API.
setTimeout(() => {
resolve("Success!") // Yay! Everything went well!
}, 250)
})
myFirstPromise
.then((res) => {
return res.json();
})
.then((data) => {
console.log(data);
})
.catch((e) => {
console.log(e);
});
then — Runs a callback you pass to it when the promise has fulfilled.
catch — Runs a callback you pass to it when something went wrong.
Async 函数为我们提供一个干净和细致的合成,使我们能够写得更少的代码,以实现相同的结果,我们会得到的承诺. Async/Await 看起来类似于同步代码,同步代码更容易阅读和写作。
const getExchangeRate = async () => {
try {
const res = await fetch('https://getExchangeRateData');
const data = await res.json();
console.log(data);
} catch (err) {
console.error(err);
}
}
getExchangeRate();
结论:这些完全是JavaScript中的无同步编程的三个合成,你应该明白,所以如果可能的话,我建议你使用“承诺”或“async/await”来恢复你的无同步代码(主要是XHR请求)!