我如何从函数 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`
}
角质1
使用AngularJS的人可以通过承诺来处理这种情况。
這裡說,
承诺可以用于无与伦比的功能,并允许一个连接多个功能。
你也可以在这里找到一个好解释。
下面提到的文档中有一个例子。
promiseB = promiseA.then(
function onSuccess(result) {
return result + 1;
}
,function onError(err) {
// Handle error
}
);
// promiseB will be resolved immediately after promiseA is resolved
// and its value will be the result of promiseA incremented by 1.
孔子2及以后
在 Angular 2 中,请参见下面的例子,但建议使用 Angular 2 的观察器。
search(term: string) {
return this.http
.get(`https://api.spotify.com/v1/search?q=${term}&type=artist`)
.map((response) => response.json())
.toPromise();
}
你可以用这种方式,
search() {
this.searchService.search(this.searchField.value)
.then((result) => {
this.result = result.artists.items;
})
.catch((error) => console.error(error));
}
但TypeScript不支持本地ES6承诺,如果你想使用它,你可能需要插件。
此外,这里是承诺的规格。
起初,呼叫反馈被用于无同步操作(例如,在XMLHttpRequest API)。现在,像浏览器的Fetch API这样的基于承诺的APIs已成为默认解决方案,并且所有现代浏览器和Node.js(服务器侧)都支持更轻松的async/await合成。
一个常见的场景 - 从服务器中获取 JSON 数据 - 可以看起来如下:
async function fetchResource(url) {
const res = await fetch(url);
if (!res.ok) {
throw new Error(res.statusText);
}
return res.json();
}
在另一个功能中使用:
async function doSomething() {
try {
const data = await fetchResource("https://example.test/resource/1");
// ...
} catch (e) {
// Handle error
...
}
}
如果你设计一个现代的API,强烈建议你更喜欢基于承诺的风格,而不是呼叫回复,如果你继承了一个基于呼叫回复的API,你可以把它作为承诺:
function sleep(timeout) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, timeout);
});
}
async function fetchAfterTwoSeconds(url) {
await sleep(2000);
return fetchResource(url);
}
在Node.js中,历史上仅依赖于呼叫反馈,这种技术是如此常见,以至于它们添加了一个名为util.promisify的辅助功能。
让我们从一个简单的JavaScript功能开始:
function foo(){
// Do something
return 'wohoo';
}
let bar = foo(); // 'bar' is 'wohoo' here
这是一个简单的同步函数呼叫(每个字符串的代码在下一个字符串之前“完成”),结果是相同的预期。
function foo(){
setTimeout( ()=> {
return 'wohoo';
}, 1000)
}
let bar = foo() // 'bar' is undefined here
所以你去那里;那个延迟只是打破了我们所期望的功能!但是发生了什么事? 好吧,如果你看代码,它真的很合乎逻辑。
承诺实际上是关于它意味着什么:它意味着该功能保证你提供它在未来得到的任何产量。
function foo(){
return new Promise((resolve, reject) => { // I want foo() to PROMISE me something
setTimeout ( function(){
// Promise is RESOLVED, when the execution reaches this line of code
resolve('wohoo') // After 1 second, RESOLVE the promise with value 'wohoo'
}, 1000 )
})
}
let bar;
foo().then( res => {
bar = res;
console.log(bar) // Will print 'wohoo'
});
更新(与 async/await 承诺)
此分類上一篇: Catch Version:
function saveUsers(){
getUsers()
.then(users => {
saveSomewhere(users);
})
.catch(err => {
console.error(err);
})
}
async/await 版本:
async function saveUsers(){
try{
let users = await getUsers()
saveSomewhere(users);
}
catch(err){
console.error(err);
}
}
JavaScript 是单一的 threaded。
浏览器可以分为三个部分:
这是一个对一个进行的曲线,并放入事件圈,执行这个函数,并在第一次执行后为下一个做好准备,这意味着执行一个函数不会开始,直到在事件圈中执行之前的函数。
它从事件路由中取出这个功能,并与服务器进行交易,使事件路由免费,以便我们可以从路由中执行下一个功能。
假设我们的服务器Request()函数有一个返回声明的代码. 当我们从服务器 Web API 恢复数据时,它将推到尾部的尾部。
因此,这个问题的解决方案是召回或承诺。
此分類上一篇
function doAjax(callbackFunc, method, url) {
var xmlHttpReq = new XMLHttpRequest();
xmlHttpReq.open(method, url);
xmlHttpReq.onreadystatechange = function() {
if (xmlHttpReq.readyState == 4 && xmlHttpReq.status == 200) {
callbackFunc(xmlHttpReq.responseText);
}
}
xmlHttpReq.send(null);
}
在我的代码中,它被称为:
function loadMyJson(categoryValue){
if(categoryValue === "veg")
doAjax(print, "GET", "http://localhost:3004/vegetables");
else if(categoryValue === "fruits")
doAjax(print, "GET", "http://localhost:3004/fruits");
else
console.log("Data not found");
}
JavaScript.info 回复